我正在使用JIBX将XML数据映射到Java对象。当XML仅包含一个目标命名空间时,这非常有效。不幸的是,需求已经改变,现在我在内部获得了带有两个不同命名空间的XML数据。
示例:
<a:foo>
<b:bar>Simple Example</b:bar>
</a:foo>
我的问题是,如何编写一个产生两个不同目标命名空间的xsd?
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="namespace_of_a"
xmlns:a="namespace_of_a"
xmlns:b="namespace_of_b"
elementFormDefault="qualified">
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<!-- this won't work, because b is part of a different namespace -->
<xs:attribute type="xs:string" use="required" name="bar"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
我已经尝试过:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="namespace_of_a"
xmlns:a="namespace_of_a"
xmlns:b="namespace_of_b"
elementFormDefault="qualified">
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<!-- this won't work, because jibx is reporting that targetNamespace is an unknown attribute -->
<xs:attribute targetNamespace="namespace_of_b" type="xs:string" use="required" name="bar"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
请帮忙。我不确定这一般是否可行?提前致谢!
答案 0 :(得分:1)
是的,这是可能的。这是XSD旨在处理的核心方案之一。
(1)为所涉及的每个命名空间编写单独的模式文档,并将该命名空间作为targetNamespace
元素的xs:schema
给出。
如果您的a:foo
元素只能接受b:bar
元素作为子元素,那么在a
的架构文档中,您将要导入名称空间b
,以便a:foo
的内容模型可以引用元素b:bar
。例如,修改示例模式文档以包括:
<xs:import namespace="namespace_of_b"/>
(注意:有些人会在这里添加schemaLocation
提示;我不会。)
然后将a:foo
的声明更改为:
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<xs:element ref="b:bar"/>
</xs:sequence>
</xs:complexType>
</xs:element>
如果a:foo
可以接受任何内容,那么在其内容模型中使用xs:any
通配符,您无需导入名称空间b
(因为您没有提及任何内容)在它)。
在命名空间b
的架构文档中,以正常方式定义元素bar
(或属性bar
- 我认为您必须改变主意如何呈现示例)
(2)编写一个简单的顶级“驱动程序”架构文档,该文档导入您在步骤1中准备的两个特定于命名空间的架构文档。这里的xs:import
语句中我提供了架构位置信息。
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="namespace_of_a" schemaLocation="a.xsd"/>
<xs:import namespace="namespace_of_b" schemaLocation="b.xsd"/>
</xs:schema>
通过要求另一个模式文档,将有关模式文档的物理位置的信息分离到单个驱动程序文件中会使问题在短期内变得复杂。但它避免了一些令人讨厌的问题,当你想稍后改变一些事情时会出现这些问题。