如何从完全转义的 Xml 字符串创建 Xml 文档?

How to create a Xml Document from a fully escaped Xml string?

问题背景:

我有一个来自 Web 服务的 XML 响应(我无法控制其内容),我想对其进行验证。例如,响应中通常会有一个 URL,其中包含使用“&”的查询字符串参数。

代码:

下面的代码给出了一个转义带有非法字符的XML字符串的例子。这确实会产生一个转义字符串:

string xml = "<node>it's my \"node\" & i like it<node>";
string encodedXml = System.Security.SecurityElement.Escape(xml);

// RESULT: &lt;node&gt;it&apos;s my &quot;node&quot; &amp; i like it&lt;node&gt;

如果我知道尝试将这个转义的 XML 加载到新的 Xml 文档中,我将收到一个错误,指出 XML 的第一个字符无效:

var doc = new XmlDocument();

// Error will occur here.
doc.LoadXml(encodedXml);

错误输出:

Data at the root level is invalid. Line 1, position 1.

如何将这个转义的 XML 加载到 XML 文档对象中?

这不是有效的 XML 文档:

&lt;node&gt;it&apos;s my &quot;node&quot; &amp; i like it&lt;node&gt;

当您转义标签上的尖括号时,XML 解析器不再将它们视为标签。它只是一个元素中的文本——但没有包含它的元素。在XML中,必须有一个根元素。这是一个要求。这可能是一个任意的要求,也可能是不公正的,但你永远不会赢得与解析器的争论。

你所做的就像将它提供给 C# 编译器:

string s = \"foo\" bar\";

不应转义外引号。

这就是你想要的:

string xml = "<node>it&apos;s my &quot;node&quot; &amp; i like it</node>";

另请注意,您原来的 XML 已经损坏

string xml = "<node>it's my \"node\" & i like it<node>";

您的 "closing" 标签不是结束标签。应该是 </node>,而不是 <node>

如果您收到来自另一个网络应用程序/API/服务的响应,则内容很可能是 Html 编码的。

看看 WebUtility class,特别是 HtmlDecode and UrlDecode。这可能会将您的 "string" 数据转换为正确的 Xml.

如果您从服务收到有效的 XML 返回信息,您可以使用如下方式转换响应:

//...
WebResponse response = request.GetResponse();
XDocument doc = XDocument.Parse
((
    new System.IO.StreamReader
    (
        response.GetResponseStream()
    )
).ReadToEnd());

如果您从应该 return 有效 XML 的服务中收到无效的 XML,请联系 owns/provides 该服务的任何人/向他们提出支持请求合适的方式。

任何其他行为都是黑客行为。有时这可能是必需的(例如,当您处理一个不再支持的遗留系统时,它的错误从未得到纠正),但首先要追求非 hacky 路线。