如何解析节点名称中包含无效字符的 XML?
Posted
技术标签:
【中文标题】如何解析节点名称中包含无效字符的 XML?【英文标题】:How To Parse XML With Invalid Characters in Node Name? 【发布时间】:2010-11-07 08:01:29 【问题描述】:所以我试图解析一些 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 解析器之前由其他工具进行预处理。 ID_INTERNAL_FEAT_FOCUSED_EXPERTISE_(MORNINGSTAR) 看起来像是在查找实际应该存在的内容。 【参考方案1】:这根本是无效的。预处理是您最好的选择,也许使用正则表达式 - 类似于:
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 - 愿意提供具体建议吗? 正则表达式大部分工作,但不知何故,上例中的倒数第二个节点在 '(' 和 ')' 完好无损的情况下仍然存在:\ 谢谢。我是这个 XML 文档的第三方,所以我不能要求修复它。但是使用正则表达式,现在它可以工作了。【参考方案2】:如果它在语法上无效,则不是 XML。
XML 对此非常严格。
如果您无法让发送应用程序发送正确的 XML,那么只需让他们知道无论下游进程看到此将失败,无论是您的还是其他人未来的其他应用程序。
如果预处理不是一个选项,另一种巧妙的机制是包装Stream
对象,该对象使用自定义流传递给解析器。该流可以寻找<
字符,当它看到一个时,设置一个标志。在看到>
字符之前,它可以吃掉任何(
或)
字符。我们已经使用类似这样的方法来消除通过旧传输机制添加到 XML 文件中的 NUL 和 ^Z 字符。 (唯一的问题可能是属性内有 <
字符,因为它们不必在那里转义 - 只有 >
字符可以。)
【讨论】:
以上是关于如何解析节点名称中包含无效字符的 XML?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 摘要中包含 html 标记,以便将其作为文本处理(不解析为 XML)?
如何使用 Boost ptree C++ 解析其值中包含 HTML 标记的 XML