如何解析节点名称中包含无效字符的 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 对象,该对象使用自定义流传递给解析器。该流可以寻找&lt; 字符,当它看到一个时,设置一个标志。在看到&gt; 字符之前,它可以吃掉任何() 字符。我们已经使用类似这样的方法来消除通过旧传输机制添加到 XML 文件中的 NUL 和 ^Z 字符。 (唯一的问题可能是属性内有 &lt; 字符,因为它们不必在那里转义 - 只有 &gt; 字符可以。)

【讨论】:

以上是关于如何解析节点名称中包含无效字符的 XML?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 摘要中包含 html 标记,以便将其作为文本处理(不解析为 XML)?

C# 压缩文件。如何提取或跳过名称中包含无效字符的文件?

如何使用 Boost ptree C++ 解析其值中包含 HTML 标记的 XML

关于ribo的代码来解析从apk到xml的信息

Retrofit-2.0 - 解析在 xml 中包含 json 的响应

请求在 Graphql 解析器中未定义,但在中间件中包含一些值。 (节点,快递)