用&符号解析XML

时间:2009-09-24 19:57:32

标签: c# xml xelement

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

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

XElement.Parse(HttpUtility.HtmlDecode(test));

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

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

吨 或者甚至尝试过这个:

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

9 个答案:

答案 0 :(得分:18)

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

例如,"wow&amp;".Replace("&", "&amp;")会产生wow&amp;amp;,这显然是不受欢迎的。

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

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

以上作品,但无可否认,它并未涵盖以&符开头的各种其他字符,例如&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);

请记住,上面的正则表达式只针对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);

答案 1 :(得分:14)

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

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

答案 2 :(得分:3)

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

&amp;   & 
&apos;  ' 
&quot;  " 
&lt;    < 
&gt;    > 

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

你应该'编码'而不是解码。但是调用HttpUtility.HtmlEncode对你没有帮助,因为它会对你的'&lt;'进行编码和'&gt;'符号以及您的字符串将不再是XML。

我认为对于这种情况,最好的解决方案是替换'&amp;'与'&amp;放大器;” (没有空格)

答案 6 :(得分:0)

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

答案 7 :(得分:0)

这是最简单,最好的方法。适用于所有字符,并允许解析任何Web服务调用(即SharePoint ASMX)的XML。

public string XmlEscape(string unescaped)
        {
            XmlDocument doc = new XmlDocument();
            var node = doc.CreateElement("root");
            node.InnerText = unescaped;
            return node.InnerXml;
        }

答案 8 :(得分:0)

Filip's的答案是正确的,但是您可以劫持System.Xml.XmlDocument类来为您完成此任务,而无需使用全新的实用程序功能。

XmlDocument doc = new XmlDocument();
string xmlEscapedString = (doc.CreateTextNode("Unescaped '&' containing string that would have broken your xml")).OuterXml;