将带有"&"的XML读取到C#XMLDocument对象中
我继承了一个写得不好的Web应用程序,当它尝试读取存储在数据库中且带有"&"的xml文档时,它似乎出错。例如,将有一个带有内容的标签:"预付费和收费"。是否有一些简单的秘密事情要做,以使它在解析该字符时不会出错,还是我遗漏了一些明显的东西?
编辑:
是否还有其他字符会由于格式不正确而导致这种类型的解析器错误?
解决方案
我们可以将&替换为&
或者,我们也可以使用CDATA节。
问题是xml格式不正确。正确生成的xml将列出如下数据:
Prepaid & Charge
我之前必须修复相同的问题,并且使用此正则表达式做到了:
Regex badAmpersand = new Regex("&(?![a-zA-Z]{2,6};|#[0-9]{2,4};)");
将其与定义如下的字符串常量结合:
const string goodAmpersand = "&";
现在我们可以说badAmpersand.Replace(<输入>,goodAmpersand);
请注意,简单的String.Replace("&","&")
不够好,因为我们无法提前知道给定文档是否会正确,不正确地编码甚至所有&字符在同一文档中。
这里的要点是,在将XML文档加载到解析器之前,必须对XML文档执行此操作,这可能意味着需要对其进行额外的传递。同样,它也不考虑CDATA部分中的"&"号。最后,它只捕获"&"号,不捕获其他非法字符,如<。更新:根据评论,我还需要更新十六进制编码(&#x ...;)实体的表达式。
关于哪些字符可能导致问题,实际规则有些复杂。例如,数据中允许某些字符,但不能作为元素名称的首字母。而且没有简单的非法字符列表。取而代之的是,一大堆(非连续的)UNICODE被定义为合法,除此之外的任何东西都是非法的。
因此,归根结底,我们必须信任文档源,以至少具有一定程度的合规性和一致性。例如,我发现人们通常很聪明,可以确保标签正常工作并逃避<,即使他们不知道&不允许,也就是今天的问题。但是,最好的办法是从源头上解决此问题。
哦,还有关于CDATA建议的注释:我将使用它来确保所创建的xml格式正确,但是从外部处理现有xml时,我发现regex方法更容易。
Web应用程序没有错,XML文档也没有错。 XML中的"&"号应编码为"&"。否则会导致语法错误。
编辑:在回答后续问题时,是的,存在各种类似的错误。例如,不平衡的标签,未编码的小于号,未加引号的属性值,字符编码之外的八位字节和各种Unicode奇数,无法识别的实体引用等。为了使任何体面的XML解析器都能使用文档,该文档必须格式正确。 XML规范要求解析器遇到格式错误的文档时会引发致命错误。
有几个字符会导致XML数据被报告为格式错误。
从w3schools:
Characters like "<" and "&" are illegal in XML elements.
我们无法信任的XML兼容输入的最佳解决方案是将其包装在CDATA标记中,例如
<![CDATA[This is my wonderful & great user text]]>
解析器将忽略<![CDATA [和
]]>`标记内的所有内容。
其他答案都是正确的,我同意他们的建议,但我只想添加一件事:
请不要使使用非格式XML的应用程序工作,这只会使我们的余生变得更加困难:)。
当然,有时候,如果我们无法控制另一端,我们实际上只是别无选择,但我们确实应该让它引发致命错误,并大声而明确地抱怨发生此类事件时发生了什么。
我们可能会更进一步,然后说:" Ack!由于这些原因,该XML损坏了,由于这些原因,这就是我尝试对其进行修复以使其格式正确的方法:..."。
我不太熟悉MSXML API,但是大多数优秀的XML解析器都允许我们安装错误处理程序,以便我们可以捕获出现错误的确切行/列号,并获取错误代码和消息。
数据库不包含XML文档。它包含一些格式正确的XML文档和一些类似于人类的XML字符串。
如果有可能,我们应该特别修复此问题,应该修复任何生成格式错误的XML文档的过程。修复从数据库读取数据的程序,只是将墙纸放在墙的裂缝上。