用&符号解析XML

par*_*oir 16 c# xml xelement

我有一个包含XML的字符串,我只想解析成Xelement,但它有一个&符号.我仍然有问题用HtmlDecode解析它.有什么建议吗?

string test = " <MyXML><SubXML><XmlEntry Element="test" value="wow&" /></SubXML></MyXML>"; 

XElement.Parse(HttpUtility.HtmlDecode(test));
Run Code Online (Sandbox Code Playgroud)

我还添加了这些方法来替换这些字符,但我仍然得到XMLException.

string encodedXml = test.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("\"", "&quot;").Replace("'", "&apos;");
XElement myXML = XElement.Parse(encodedXml);
Run Code Online (Sandbox Code Playgroud)

或者甚至尝试过这个:

string newContent=  SecurityElement.Escape(test);
XElement myXML = XElement.Parse(newContent);
Run Code Online (Sandbox Code Playgroud)

Ahm*_*eed 20

理想情况下,在代码使用XML之前,XML会被正确转义.如果这超出了您的控制范围,您可以编写正则表达式.除非您完全确定这些值不包含其他转义项,否则请勿使用String.Replace方法.

例如,"wow&amp;".Replace("&", "&amp;")结果wow&amp;amp;显然是不合需要的.

Regex.Replace可以为您提供更多控制以避免这种情况,并且可以编写为仅匹配不属于其他字符的"&"符号,例如&lt;:

string result = Regex.Replace(test, "&(?!(amp|apos|quot|lt|gt);)", "&amp;");
Run Code Online (Sandbox Code Playgroud)

上面的工作,但不可否认它并没有涵盖以&符号开头的各种其他字符,例如,&nbsp;列表可以增长.

更灵活的方法是解码value属性的内容,然后重新编码它.如果你有value="&wow&amp;"解码过程将返回"&wow&"然后重新编码它将返回"&amp;wow&amp;",这是可取的.要解决此问题,您可以使用此方法:

string result = Regex.Replace(test, @"value=\""(.*?)\""", m => "value=\"" +
    HttpUtility.HtmlEncode(HttpUtility.HtmlDecode(m.Groups[1].Value)) +
    "\"");
var doc = XElement.Parse(result);
Run Code Online (Sandbox Code Playgroud)

请记住,上面的正则表达式只针对value属性的内容.如果XML结构中还有其他区域遇到同样的问题,那么可以调整它以匹配它们并以类似的方式替换它们的内容.


编辑:更新的解决方案,应处理标签之间的内容以及双引号之间的任何内容.一定要彻底测试.尝试使用正则表达式操作XML/HTML标记是不利的,因为它可能容易出错并且过于复杂.您的情况有点特殊,因为您需要首先对其进行消毒才能使用它.

string pattern = "(?<start>>)(?<content>.+?(?<!>))(?<end><)|(?<start>\")(?<content>.+?)(?<end>\")";
string result = Regex.Replace(test, pattern, m =>
            m.Groups["start"].Value +
            HttpUtility.HtmlEncode(HttpUtility.HtmlDecode(m.Groups["content"].Value)) +
            m.Groups["end"].Value);
var doc = XElement.Parse(result);
Run Code Online (Sandbox Code Playgroud)

  • &amp; 符号后面也可以跟数字代码。’ 也可以表示为 ' 或' 或' 使用: string result = Regex.Replace(test, @"&amp;(?!(quot|amp|apos|lt|gt|#x?\d{2,3});)", "&amp;"); (2认同)

Jus*_*ner 14

您的字符串不包含有效的XML,这就是问题所在.您需要将字符串更改为:

<MyXML><SubXML><XmlEntry Element="test" value="wow&amp;" /></SubXML></MyXML>"
Run Code Online (Sandbox Code Playgroud)


Tom*_*ier 0

如果您的字符串不是有效的 XML,它将不会解析。如果它本身包含 & 符号,则它不是有效的 XML。与 HTML 相反,XML 非常严格。