用&符号解析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正在做的事情,能够忽略未用作实体引用的&符号。