使用“&”将XML读入C#XMLDocument对象

我inheritance了一个编写得很糟糕的Web应用程序,它在尝试读入存储在数据库中的“&”中的xml文档时似乎有错误。 例如,将有一个标签包含内容:“预付费和费用”。 是否有一些秘密简单的事情可以让它解析那个角色时没有错误,或者我错过了一些明显的东西?

编辑:是否有任何其他字符会导致相同类型的解析器错误不正确?

问题是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文档执行此操作,这可能意味着额外的通过它。 此外,它没有考虑CDATA部分内的&符号。 最后, 它只捕获&符号,而不是其他非法字符,如<。 更新:根据评论,我还需要更新hex编码(&#x …;)实体的表达式。

关于哪些字符可能导致问题,实际规则有点复杂。 例如,数据中允许使用某些字符,但不能作为元素名称的第一个字母。 而且没有简单的非法字符列表。 相反,一个大的(非连续的)UNICODE区域被定义为合法的 ,除此之外的任何东西都是非法的。

因此,当涉及到它时,您必须相信您的文档源至少具有一定的合规性和一致性。 例如,我发现人们通常足够聪明,以确保标签正常工作并逃脱<,即使他们不知道&不被允许,因此今天你的问题。 但是, 最好的方法是在源头修复此问题。

哦,以及关于CDATA建议的说明:我使用它来确保我正在创建的 xml格式正确,但是当从外部处理现有的xml时,我发现正则表达式方法更容易。

Web应用程序没有错,XML文档是。 XML中的&符号应编码为& 。 不这样做是语法错误。

编辑:在回答后续问题时,是的,有各种类似的错误。 例如,不平衡标签,未编码的小于标志,不带引号的属性值,字符编码之外的八位字节和各种Unicode奇怪,无法识别的实体引用等等。 为了使任何合适的XML解析器使用文档,该文档必须格式良好。 XML规范要求解析器遇到格式错误的文档会导致致命错误。

其他答案都是正确的,我同意他们的建议,但我只想补充一点:

请不要使应用程序与非格式良好的XML一起工作,这只会让我们的余生变得更加困难:)。

当然,有些时候你真的只是没有选择,如果你无法控制另一端,但你真的应该抛出一个致命的错误,并且非常大声地抱怨当发生这样的事件时会发生什么损坏。

您可以更进一步说“Ack!这些XML在这些地方被打破了,出于这些原因,这就是我试图修复它以使其形成良好的forms:……”。

我并不过分熟悉MSXML API,但是大多数优秀的XML解析器都允许您安装error handling程序,以便您可以捕获出现错误的确切行/列号以及获取错误代码和消息。

您的数据库不包含XML文档。 它包含一些格式良好的XML文档和一些看起来像XML的字符串。

如果可能的话,你应该解决这个问题 – 特别是,你应该修复生成格式错误的XML文档的任何进程。 修复从该数据库中读取数据的程序只是将壁纸放在墙上的裂缝中。

您可以替换&

或者您也可以使用CDATA部分。

有几个字符会导致XML数据报告为格式错误。

来自w3schools :

像“<”和“&”这样的字符在XML元素中是非法的。

对于您不能信任符合XML的输入的最佳解决方案是将其包装在CDATA标签中,例如

  

解析器会忽略]]>标记内的所有内容。