如何解析包含无效字符的XML节点名称?

3

我正在尝试解析一些XML,但它们的创建不受我的控制。问题是,它们有一些节点看起来像这样:

<ID_INTERNAL_FEAT_FOCUSED_EXPERTISE_(MORNINGSTAR) />
<ID_INTERNAL_FEAT_FOCUSED_EXPERTISE_(QUARTERSTAFF) />
<ID_INTERNAL_FEAT_FOCUSED_EXPERTISE_(SCYTHE) />
<ID_INTERNAL_FEAT_FOCUSED_EXPERTISE_(TRATNYR) />
<ID_INTERNAL_FEAT_FOCUSED_EXPERTISE_(TRIPLE-HEADED_FLAIL) />
<ID_INTERNAL_FEAT_FOCUSED_EXPERTISE_(WARAXE) />

Visual Studio和.NET都认为上述使用的'('和')'字符是完全无效的。不幸的是,我需要处理这些文件!有没有办法让Xml Reader类在看到这些字符时不会发疯,或者动态地转义它们或做些什么?我可以对整个文件进行某种预处理,但如果它们以某种有效的方式出现在节点内部,我确实希望保留'('和')'字符,因此我不想将它们全部删除...


如果不是有效的XML,则不是XML。无论如何,将其处理为文本。 - Remus Rusanu
2
这个文件看起来应该在发送到XML解析器之前由其他工具进行预处理。ID_INTERNAL_FEAT_FOCUSED_EXPERTISE_(MORNINGSTAR)看起来像是实际应该存在的内容的查找。 - Dolphin
2个回答

8

这个想法是不正确的。最好的方法是使用预处理,可以考虑使用正则表达式,比如:

string output = Regex.Replace(input, @"(<\w+)\((\w+)\)([ >/])", "$1$2$3");

编辑:替换括号内部的“-”有点复杂:

string output = Regex.Replace(input, @"(<\w+)\(([-\w]+)\)([ >/])",
    delegate(Match match) {
        return match.Groups[1].Value + match.Groups[2].Value.Replace('-', '_')
             + match.Groups[3].Value;
    });

我会尝试使用最严格的正则表达式。 - Dolphin
@ Dolphin - 你能提供一个具体的建议吗? - Marc Gravell
正则表达式大部分都能工作,但是在上面的例子中,倒数第二个节点以 '(' 和 ')' 的形式幸存了下来 : \ - GWLlosa
谢谢。我是这个XML文档的第三方,所以我并没有权利要求对其进行修复。但是有了正则表达式,现在它可以工作了。 - GWLlosa

3
如果它不符合语法规则,那么它就不是XML。
XML在这方面非常严格。
如果您无法让发送应用程序发送正确的XML,则只需让他们知道任何将看到此错误的“下游”进程(无论是您的应用程序还是将来的其他应用程序)都将失败。
如果预处理不是一个选项,另一种聪明的机制是使用自定义流来包装传递给解析器的“Stream”对象。该流可以查找<字符,并在找到一个时设置标志。在看到>字符之前,它可能会吞掉任何(或)字符。我们曾经使用过类似的方法来消除遗留传输机制添加到XML文件中的NUL和^Z字符。(唯一需要注意的是,在属性中可能存在<字符,因为它们不必在那里转义-只有>字符必须这样做。)

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