RFC:在JDK 1.5和1.6中XSD验证

发布    |       讨论区

在Hibernate中,存在一种特定的逻辑分支,我们需要解析和验证org.xml.sax.InputSource,它可能代表Hibernate映射(hbm.xml)文件、1.0兼容的orm.xml文件或2.0兼容的orm.xml文件。目前,Hibernate映射文件由DTD定义,而orm.xml文件的两个版本由XSD定义。当前代码构建一个启用DTD和Schema验证的SAXReader并尝试读取源。它首先将Schema验证映射到XSD的2.0版本;如果发生错误,它将尝试重新解析映射Schema验证到1.0版本的XSD。

我不是XML专家,但我觉得这很浪费。但无论如何尝试,我找不到一种方法来说明我们需要解析XSD到单个文件(本地)如果根元素的version=2.0作为属性,否则为另一个version=1.0。实际上,这似乎是一个条件解析schemaLocation的问题。有人知道这是否可能吗?

我的下一个想法是利用JDK 1.5中添加的javax.xml.validation.Validator契约。基本上,我会在解析文档期间启用文档的DTD验证,并简单地解析文档。然后我查看根元素以确定文档是Hibernate映射还是orm.xml。如果orm.xml,我然后检查其version属性,根据适当的XSD加载验证器,并执行Validator.validate(new DOMSource(...))。首先,由于分开的解析和验证步骤,这会慢多少?

此外,我遇到了一个非常令人烦恼的问题。在我的测试中,我创建了一个符合2.0 Schema的文档,但将其版本标识为1.0并使用了1.0版本的Schema。在(Sun)JDK 1.6中运行时测试成功,验证器确实提出了抱怨;但在(Sun)JDK 1.5中验证器根本没有任何抱怨。1.5和1.6似乎使用不同的内部SchemaFactory实现。1.6使用com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory,而1.5使用com.sun.org.apache.xerces.internal.jaxp.validation.xs.SchemaFactoryImpl。

可能我只是做错了什么?代码可以在https://fisheye2.atlassian.com/browse/Hibernate/core/trunk/core/src/main/java/org/hibernate/util/xml/MappingReader.java?r=20321#l118(这是被注释掉的代码)中查看。

假设我没有犯错,最好的解决办法是什么?


回到顶部