C#加载SQL Xml类型数据到XmlDocument时避免<被转义为<的方法
问题根因
转义不是发生在XmlDocument.Save环节,问题出在节点插入逻辑:你通过CreateTextNode将newXML.OuterXml(XML结构化字符串)作为纯文本节点插入目标文档。按照XML规范,文本节点内的</>/&等特殊字符必须被转义为实体形式,因此尖括号被自动转为</>是符合标准的默认行为,不是程序异常。
你之前尝试的字符串替换、编码指定、WebUtility解码等方案无效,是因为这些方法没有改变「把XML结构当纯文本插入」的本质,DOM序列化文本节点时依然会执行强制转义。
正确解决方案
不要将源XML转为字符串后作为文本插入,直接通过DOM节点导入的方式,把源XML的节点结构导入目标文档后追加,插入的是真实的XML元素节点而非文本,自然不会触发转义,也不需要CDATA标签。
修正后的完整代码
- 模拟读取SQL XML数据载入XmlDocument(这部分无需修改)
XmlDocument newXML = new XmlDocument(); newXML.LoadXml("<root><Output>Craig</Output></root>");
- 初始化输出文档(去掉原代码里多余的误输入反引号即可)
XmlDocument xmlOutputDoc = new XmlDocument(); // 创建XML声明 XmlDeclaration xmlDeclaration = xmlOutputDoc.CreateXmlDeclaration("1.0", "UTF-8", null); xmlOutputDoc.InsertBefore(xmlDeclaration, xmlOutputDoc.DocumentElement); // 创建根节点 XmlElement RootElement = xmlOutputDoc.CreateElement(string.Empty, "root", string.Empty); xmlOutputDoc.AppendChild(RootElement);
- 导入源XML节点到输出文档(替换原来创建文本节点的错误逻辑)
// 创建Output元素 XmlElement Output = xmlOutputDoc.CreateElement("Output", string.Empty); RootElement.AppendChild(Output); // 将源XML的根节点递归导入到目标文档(第二个参数true表示导入所有层级子节点) XmlNode importedSourceNode = xmlOutputDoc.ImportNode(newXML.DocumentElement, true); // 将导入的节点追加到Output元素下 Output.AppendChild(importedSourceNode);
输出结果
执行保存后得到的XML内容完全符合预期,无多余转义、无CDATA标签:
<?xml version="1.0" encoding="UTF-8"?> <root> <Output> <root> <Output>Craig</Output> </root> </Output> </root>
不推荐的方案说明
XmlWriter.WriteRaw:可以强行输出未转义的尖括号,但会绕过XML DOM的格式校验,极易生成不符合规范的无效XML,后续解析很容易出错- 序列化后字符串替换:在Save生成最终字符串后强行替换
<为<,同样会破坏XML合法性,遇到文本内容里本来就需要保留转义的<时会出现逻辑错误
内容的提问来源于stack exchange,提问作者Craig
相关产品推荐
相关产品推荐

