【发布时间】:2014-10-26 16:52:30
【问题描述】:
我正在尝试针对 XMLSchema.xsd 验证最简单的 XSD 文件:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="a" type="xs:int"/>
</xs:schema>
为此,我下载了文件 XMLSchema.xsd 并将其传递给我的org.w3c.dom.ls.LSResourceResolver,以确保使用本地提供的XMLSchema.XSD 而不是通过 Internet 获取的。代码在我的类路径上以Saxon-HE-9.4.jar 运行。
但是这失败了:
org.xml.sax.SAXParseException; cvc-elt.1:找不到元素“xs:schema”的声明。
这似乎与之前的消息有关(由我的自定义 LSResourceResolver 子类发出):
未能读取架构文档“[...]XMLSchema.xsd”,因为 1) 找不到该文档; 2) 文件无法读取; 3)文档的根元素不是
。
但是,当我注释掉 XMLSchema.XSD 文件中的整个 DOCTYPE 部分时,它正在工作。
我猜这意味着解析器无法处理XMLSchema.xsd 中的DOCTYPE 和ATTLIST 子句。
所以我有两个问题:
- 为什么解析器无法处理
XMLSchema.xsdXML prolog?有什么方法可以解决这个问题而无需编辑XMLSchema.xsd文件? - 如果没有办法绕过#1,我如何从http://www.w3.org/2001/XMLSchema.xsd 下载
XMLSchema.xsd文件而不使用XML prolog,这样我就不必手动编辑。一个简单的wget也会获取 XML 序言(顺便说一句,当使用浏览器访问链接时不会出现该序言)。
这确实太大了,无法提供 SSCCE,但如果有人想看看,我会提供一个带有测试用例的 github 存储库。
【问题讨论】:
-
只是想知道:您使用的是 DOM 文档吗?如果是这样,您是在创建时将验证设置为 false 还是将其保留为默认 true?
-
@nablex 是的,文件被读取为
org.w3c.dom.Document;在我调用的DocumentBuilderFactory对象上:setValidating(false); -
你已经用“saxon”和“xerces”标记了这个。这两个都提供了模式验证器,但是您还没有明确说明您正在使用哪个。我从您正在使用 xerces 模式验证器的错误消息中得到印象;那你为什么用“撒克逊”来标记这个问题?
-
@MichaelKay 你是对的,我使用的
Validator属于org.apache.xerces.jaxp.validation.ValidatorImpl。实际上我只是在做一个Validator validator = schema.newValidator(),因为我只引入了 saxon 作为依赖项,所以我假设使用了 Saxon 验证器。显然,saxon 引入了 Xerces 和 Xalan 作为传递依赖项,因此最终使用了 Xerces 验证器。有没有办法更明确地控制创建哪个验证器?我已经删除了撒克逊标签。 -
如果您想通过 JAXP 接口使用 Saxon 进行模式验证,那么您可以使用 JAXP 模式工厂接口来完成,但不能通过在 XML 解析器上设置验证属性,因为 Saxon 验证器不是与解析器集成,它是独立的。