用&符号解析XML

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

string test = " "; XElement.Parse(HttpUtility.HtmlDecode(test)); 

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

 string encodedXml = test.Replace("&", "&").Replace("", ">").Replace("\"", """).Replace("'", "'"); XElement myXML = XElement.Parse(encodedXml); 

或者甚至尝试过这个:

 string newContent= SecurityElement.Escape(test); XElement myXML = XElement.Parse(newContent); 

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

例如, "wow&".Replace("&", "&")导致wow& 这显然是不受欢迎的。

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

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

上述作品,但无可否认,它并未涵盖以&符号开头的各种其他角色,例如  并且列表可以增长。

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

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

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


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

 string pattern = "(?>)(?.+?(?))(?<)|(?\")(?.+?)(?\")"; 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); 

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

 " 

HtmlEncode不会起作用,它可能会创建更多的&符号(例如,’可能会变成’,这是一个Xml实体引用,如下所示:

 & & ' ' " " < < > > 

但它可能会得到类似的东西,这在html中很好,但在Xml中却没有。 因此,像其他人说的那样,首先纠正xml,确保任何属于你的XML实际标记的字符(也就是说, 任何内容都在你的xml中作为变量或文本 )并且在实体引用中出现list被转换为它们对应的实体(所以<将成为<)。 如果包含非法字符的文本是xml节点内的文本,则可以采用简单的方法并使用CDATA元素包围文本,但这对于属性不起作用。

ampersant使XML无效。 这不能通过样式表来修复,因此您需要使用VB / C#/ PHP / Delphi / Lisp / Etc中的其他工具或代码编写代码。 删除它或将其翻译为&amp ;.

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

你应该’编码’而不是解码。 但是调用HttpUtility.HtmlEncode对你没有帮助,因为它会对你的’<'和'>‘符号进行编码,你的字符串将不再是XML。

我认为对于这种情况,最好的解决方案是将’&’替换为’&amp;’ (没有空间)

也许考虑编写自己的XMLDocumentScanner。 这就是NekoHTML正在做的事情,能够忽略未用作实体引用的&符号。