2

我们有一个沼泽标准javax.xml.*解析器,它会抓取一个大的 XML 文件并尝试根据自定义 DTD 对其进行验证。DTD 存储在本地,我们正在使用几年前的这篇文章中的转换器进行验证。

所有这些都有效。我们现在看到的问题是这种文件的 XML 格式是魔鬼写的。我不是在开玩笑; 该规范超过 750 页,署名“爱,撒旦”。

具体来说,部分 XML 如下所示:

<KnownTag>
    <ArbitraryTag> ... text ... </ArbitraryTag>
    <Whatever>     ... text ... </Whatever>
    <fj9e8jer23tj> ... text ... </fj9e8jer23tj>
    ....
</KnownTag>

内部标签是平衡的——在这一点上,原始语法被认为是格式良好的 XML——但元素名称本身是完全任意的和不可预测的。(是的,就是这么邪恶。最初发布这个规范的公司早就倒闭了,因为他们的产品出了名的不可靠。去想一想。)

我们的自定义 DTD 可以指定<!ELEMENT KnownTag ANY>,但我们已经适应了内容。显然,验证解析器在遇到第一个用户指定的元素名称时会立即给出错误(必须声明元素类型“ArbitraryTag”),显然我们不能从纯粹的解析上下文中真正“验证”该块内的任何内容。我希望找到某种方法来抑制 XML 的那一部分的错误。

  • 解析器的错误处理接口ErrorHandler指定了 3 个回调;error()在这种情况下调用它。如果我能从传入的实际异常中找出我们在一个KnownTag块内,那么我可以放心地忽略该错误并继续前进。这对 Java SE 实现安全吗?

  • 之后获取任意元素应该不成问题,因为此时 XML 解析器本身已经构建了一个 DOM 文档。

  • javax.xml.parsers.DocumentBuilder[Factory]用于和javax.xml.transform.Transformer似乎不允许DocumentBuilderFactory#setValidating()在解析中途切换的 API 。如果是这样的话,那就不足为奇了,但我希望我只是错过了一些东西。任何人?

4

1 回答 1

1

DTD 没有跳过对格式良好的 XML 的特定子树进行验证的机制;这是 DTD 和后来的模式语言(如 XSD 和 Relax NG)之间的区别之一,后者引入了通配符,可以说诸如“KnownTag元素可以包含任意 XML”(或者:不在特定命名空间中的任意元素,或在任何一组特定的命名空间,或...)。

您的解析器是否具有关闭特定子树中错误报告的功能完全是特定于解析器的;您需要描述您正在使用的许多基于 Java 的 XML 解析器中的哪一个。机会很渺茫;解析器拥有这样的功能并非不可能,但乍一看,它听起来不像符合规范的行为。(这也不是我听说过的基于 DTD 的验证器具有的功能,但这实际上并不能证明太多。)

于 2013-01-03T16:48:16.110 回答