解析包含非法字符的XML

4
我从服务器收到的一条消息包含标签,而在标签中是我需要的数据。
我试图将负载解析为XML,但会生成非法字符异常。
我还使用了httpUtility和Security Utility来转义非法字符,唯一的问题是它会转义< >,而这些字符是解析XML所必需的。
我的问题是,当数据中包含非法的非XML字符时,我该如何解析XML? (& -& gt; amp;)_
谢谢。
示例:
<item><code>1234</code><title>voi hoody & polo shirt + Mckenzie jumper</title><description>Good condition size small - medium, text me if interested</description></item>

1
您的XML文档格式不正确。服务器必须发送正确的数据。如果可能,请尝试在服务器端进行修复。描述必须是“CDATA”。 - Hamlet Hakobyan
4
既然你尝试解析的不是XML,那么你需要采取非标准的方式来解决问题。我建议修复源代码。 - spender
是的,关于服务器我无能为力。我正在尝试绕过创建自定义读取器的想法。我想通过使用XML来作弊,不知道有没有人知道如何解决上述问题。如果不行的话,看起来我必须创建自己的自定义读取器。即在标签之间阅读的读取器。 - mitchellt
1
你可以尝试使用 string.Replace() 方法来修复所有非法字符。 - Chuck Savage
3个回答

6
如果你只有一个非法字符&,那么你可以使用正则表达式将其替换为&amp;。我们使用正则表达式来防止已存在的符号&amp;&quot;&#111;等被替换。
正则表达式如下:
&(?!(?:lt|gt|amp|apos|quot|#\d+|#x[a-f\d]+);)

正则表达式可视化

示例代码:

string content = @"<item><code>1234 &amp; test</code><title>voi hoody & polo shirt + Mckenzie jumper&other stuff</title><description>Good condition size small - medium, text me if interested</description></item>";
content = Regex.Replace(content, @"&(?!(?:lt|gt|amp|apos|quot|#\d+|#x[a-f\d]+);)", "&amp;", RegexOptions.IgnoreCase);
XElement xItem = XElement.Parse(content);

2
不要称其为“包含非法字符的XML”。它不是XML。你不能使用XML工具处理不是XML的东西。
当你遇到坏的XML时,最好的方法是找出它在何时何地生成,并在源头解决问题。
如果你无法做到这一点,你需要找到一些非XML工具(例如自定义perl脚本)来修复XML,在将其放入XML解析器之前。你所采取的方式将取决于你需要修复的错误的性质。

1
这里提供了比正则表达式更通用的解决方案。首先声明一个数组,将想要替换为编码版本的每个无效字符存储到数组中:
var invalidChars = new [] { '&', other chars comes here.. };

然后将所有的XML作为整个文本进行阅读:

var xmlContent = File.ReadAllText("path");

然后使用LINQHttpUtility.HtmlEncode替换无效字符:
var validContent = string.Concat(xmlContent
        .Select(x =>
        {
            if (invalidChars.Contains(x)) return HttpUtility.HtmlEncode(x);
            return x.ToString();
        }));

然后使用XDocument.Parse进行解析,就这样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接