禁止验证XML的子部分

时间:2013-01-02 19:14:12

标签: java xml-parsing dtd

我们有一个标准的javax.xml.*解析器,它可以提供一个大的XML文件并尝试根据自定义DTD对其进行验证。 DTD存储在本地,我们在几年前使用变换器like in this post进行验证。

所有这些都有效。我们现在遇到的麻烦是这种类型的文件的XML格式是由恶魔编写的。我不是在开玩笑;该规范超过750页,并签署了“爱,撒旦。”

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

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

内部标记是平衡的 - 此时已知原始语法是格式良好的XML - 但元素名称本身完全是任意且不可预测的。 (是的,这就是邪恶。最初发布这个规范的公司早已停业,因为他们的产品众所周知是不可靠的。去看看。)

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

  • 解析器的错误处理程序接口ErrorHandler指定3个回调;在这种情况下调用它的error()。如果我可以从the actual exception passed in找出我们在KnownTag块内,那么我可以放心地忽略错误并继续前进。这与Java SE实现安全吗?

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

  • javax.xml.parsers.DocumentBuilder[Factory]javax.xml.transform.Transformer的API似乎不允许在解析的中途切换DocumentBuilderFactory#setValidating()。如果是这样的话就不会令人感到意外,但我希望我错过了一些东西。任何人

1 个答案:

答案 0 :(得分:1)

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

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