如何正确验证不同的 XSD 版本?
我正在尝试更新一些 xml 解析器,但遇到了一个小障碍。我们有一个 xsd,需要与旧版本的 xml 保持兼容,并且必须对其进行一些更改。我们在新版本的 xsd 中进行了更改,并且我们希望使用相同的解析器(因为一般来说更改非常小,并且解析器可以轻松处理两者)。我们使用 XMLReader
属性 "http://java.sun.com/xml/jaxp/properties/schemaSource"
将架构设置为以前的版本,使用一些东西如下所示:
xmlReader.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource",
new InputSource(getClass().getResourceAsStream("/schema/my-xsd-1.0.xsd")));
当我们只有一个版本的模式时,这工作得很好。现在我们有了新版本,我们希望系统使用传入 xml 中定义的模式版本。两种模式都定义了一个名称空间,如下所示:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.mycompany.com/my-xsd-1.0"
xmlns="http://www.mycompany.com/my-xsd-1.0"
elementFormDefault="unqualified" attributeFormDefault="unqualified">
并且,对于新模式:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.mycompany.com/my-xsd-1.1"
xmlns="http://www.mycompany.com/my-xsd-1.1"
elementFormDefault="unqualified" attributeFormDefault="unqualified">
因此,它们定义了不同的名称空间和不同的模式“位置”。我们不希望模式存在于网络上 - 我们希望它与我们的系统捆绑在一起。有没有办法使用 setProperty 机制来执行此行为,或者是否有不同的方法来处理此行为?
我尝试将这两个资源作为参数放入数组的输入流中,但这不起作用(我记得在某处读过这是一个可能的解决方案 - 尽管现在我找不到源,所以它可能是一厢情愿的思维)。
I am attempting to update some xml parsers, and have hit a small snag. We have an xsd that we need to keep compatible with older versions of the xml, and we had to make some changes to it. We made the changes in a new version of the xsd, and we would like to use the same parser (as the changes are pretty small in general, and the parser can easily handle both). We are using the XMLReader
property "http://java.sun.com/xml/jaxp/properties/schemaSource"
to set the schema to the previous edition, using something like the following:
xmlReader.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource",
new InputSource(getClass().getResourceAsStream("/schema/my-xsd-1.0.xsd")));
This worked fine when we only had one version of the schema. Now we have a new version, and we want the system to use whichever version of the schema is defined in the incoming xml. Both schemas define a namespace, something like the following:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.mycompany.com/my-xsd-1.0"
xmlns="http://www.mycompany.com/my-xsd-1.0"
elementFormDefault="unqualified" attributeFormDefault="unqualified">
and, for the new one:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.mycompany.com/my-xsd-1.1"
xmlns="http://www.mycompany.com/my-xsd-1.1"
elementFormDefault="unqualified" attributeFormDefault="unqualified">
So, they have different namespaces and different schema "locations" defined. We don't want the schema to live on the 'net - we want it to be bundled with our system. Is there a way to use the setProperty mechanism to do this behavior, or is there a different way to handle this?
I tried putting both resources in an input stream in an array as the parameter, but that didn't work (I remember reading somewhere that this was a possible solution - although now I can't find the source, so it might have been wishful thinking).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
所以,事实证明我所尝试的确实有效 - 我们不小心使用了无效的 xml!有效的(对于其他感兴趣的人)如下:
So, it turns out what I had tried actually worked - we were accidentally using invalid xml! What works (for anyone else who is interested) is the following:
就我个人而言,我认为在对架构进行版本控制时更改命名空间通常是一个坏主意,除非更改是彻底的 - 但对此看法不同,而且您似乎已经做出了决定,并且您也可能会从中受益。
由于您使用的是两个不同的命名空间,因此模式可能是不相交的,因此您应该能够为处理器提供一个两者并集的模式 - 我不知道是否有更好的方法,但实现此目的的一种方法的方法是编写一个导入两者的小存根模式,并提供此存根作为您的 schemaSource 属性。处理器将使用与源文档中元素的命名空间匹配的模式声明。
(使用特定于版本的名称空间使此任务(验证)更容易。但它使后续的 XML 处理(例如使用 XPath)变得更加困难,因为很难编写适用于这两个名称空间的代码。)
Personally I think it's generally a bad idea to change the namespace when you version a schema, unless the changes are radical - but views differ on that, and you seem to have made your decision, and you may as well reap the benefits.
Since you're using two different namespaces, the schemas are presumably disjoint, so you should be able to give the processor a schema that's the union of the two - I don't know if there's a better way, but one way of achieving this is to write a little stub schema that imports both, and supply this stub as your schemaSource property. The processor will use whichever schema declarations match the namespace of the elements in the source document.
(Using version-specific namespaces makes this task - validation - easier. But it makes subsequent processing of the XML, e.g. using XPath, harder, because it's hard to write code that works with both namespaces.)