用XElement添加CDATA必须使用XCData类实例,不能用字符串插值或Value属性;XCData构造函数传入纯字符串,不带CDATA外壳,且需确保内容不含"]]>”序列。

用 XElement 直接添加 XCData 是可行的,但不能用字符串插值或 Value 属性
很多人试图这样写:
XElement elem = new XElement("content", "alert(1)]]>");结果 XML 输出里全是转义字符,zuojiankuohaophpcn![CDATA[...]]youjiankuohaophpcn,根本不是真正的 CDATA。这是因为 XElement 的构造函数把字符串当普通文本处理,自动转义了尖括号和符号。
必须显式创建 XCData 实例并作为子节点传入
XCData 是 System.Xml.Linq 命名空间下的独立节点类型,它不继承自 XText,也不属于字符串内容——它是特殊节点,序列化时会原样包裹为 。
- 错误写法:
new XElement("script", "")→ 被当作文本,全部转义 - 正确写法:
new XElement("script", new XCData("")) - 也可追加:
elem.Add(new XCData("...")) - 注意:
XCData构造函数参数是纯字符串,不带和]]>外壳
嵌套、拼接与常见陷阱
CDATA 内容本身不能包含 ]]> 字符序列,否则 XML 解析器会提前截断。.NET 不会自动检测或转义它——这是你自己的责任。
- 如果原始字符串含
]]>,必须手动拆分或替换(比如改成]]> 拼接) -
XCData不能作为根节点,只能作为XElement的子节点 - 用
ToString()或Save()输出时才会体现 CDATA 包裹;调试器里看XCData对象的Value属性,显示的仍是原始字符串,别被误导 - 若混用
XText和XCData子节点,顺序保留,但 CDATA 块仍独立生效
XElement root = new XElement("root",
new XElement("description", new XCData("Line 1\r\nLine 2 with ")),
new XElement("note", "plain text"),
new XElement("code", new XCData("function() { return a < b && c > d; }"))
);
替代方案:不用 XCData 也能绕过转义?
极少数场景下,如果你只是想避免 HTML/JS 特殊字符被转义,又不强求 CDATA 语义,可考虑:
– 改用 XDocument + XmlWriter 手动写入(更底层,失去 LINQ to XML 便捷性)
– 或接受转义后的字符串(如 zuojiankuohaophpcnscriptyoujiankuohaophpcn),由前端 JS 自行解析(但已不是原始 CDATA 行为)
– 严格来说,只有 XCData 是标准、可靠、符合 XML 规范的 CDATA 表达方式
真正难的不是怎么加,而是确认内容里没有 ]]> —— 这个边界条件很容易漏掉。









