清除/替换元素属性中的无效XML字符

时间:2011-10-13 15:04:06

标签: c# xml regex

更新:无效字符实际上在属性中而不是元素中,这将阻止我使用下面建议的CDATA解决方案。

在我的应用程序中,我收到以下XML作为字符串。这有两个问题,为什么不接受它作为有效的XML。 希望任何人都能有一个优雅地修复这些bug的解决方案。

  1. XML中有ASCII字符是不允许的。不仅是示例中显示的那个,而且我想用相应的字符替换所有ASCII代码。

  2. 在元素中'&lt;'存在 - 我想从XML中删除所有这些“内部元素”(<L CODE=&#034;C01&#034;>WWW.cars.com</L>)。

  3. <?xml version="1.0" encoding="ISO-8859-1"?>
    <cars>
      <car model="ford" description="Argentini&#235; love this"/>
      <car model="kia" description="a small family car"/>
      <car model="opel" description="great car <L CODE=&#034;C01&#034;>WWW.cars.com</L>"/>
    </cars>
    

2 个答案:

答案 0 :(得分:3)

要快速修复,您可以将此非XML加载到字符串中,并在任何您知道通常包含无效数据的XML标记内添加[CDATA] [1]标记。例如,如果您只看到<description>标记内的错误数据,则可以执行以下操作:

var soCalledXml = ...;
var xml = soCalledXml
    .Replace("<description>", "<description><![CDATA[")
    .Replace("</description>", "]]></description>");

这会将标签变为:

<description><![CDATA[great car <L CODE=&#034;C01&#034;>WWW.cars.com</L>]]></description>

然后您可以成功处理 - 它将是<description>标记,其中包含简单字符串great car <L CODE=&#034;C01&#034;>WWW.cars.com</L>

如果<description>标签可能具有任何属性,那么这种字符串替换将充满问题。但是,如果您可以指望open标记始终是完全没有属性的字符串<description>,并且标记内没有额外的空格,并且如果您可以指望close标记始终为</description>而没有在>之前的空格,那么这应该让你知道,直到你可以说服谁产生你的垃圾输入,他们需要生成格式良好的XML。


更新

由于格式错误的数据位于属性中,因此CDATA无效。但是你可以使用正则表达式来查找这些引号字符中的所有内容,然后进行字符串操作以正确地转义<>。它们至少可以转义嵌入式引号,因此从""的正则表达式可以正常工作。

请记住,在XML上使用正则表达式通常是个坏主意。当然,你得到的实际上并不是XML,但由于所有相同的原因,仍然很难做到。所以期望它很脆弱 - 它可以用于您的示例输入,但是当它们向您发送下一个文件时它可能会中断,特别是如果它们没有正确地转义&。您最好的选择仍然是说服他们为您提供格式良好的XML。

using System.Text.RegularExpressions;

var soCalledXml = ...;
var xml = Regex.Replace(soCalledXml, "description=\"[^\"]*\"",
    match => match.Value.Replace("<", "&lt;").Replace(">", "&gt;"));

答案 1 :(得分:0)

您可以将该内容包装在CDATA部分中。

使用正则表达式,它将是这样的,匹配

"<description>(.*?)</description>" 

并替换为

"<description><![CDATA[$1]]></description>"