JIBX:如何使用多个目标命名空间?

时间:2012-08-20 10:17:36

标签: xml namespaces xsd jibx

我正在使用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>

请帮忙。我不确定这一般是否可行?提前致谢!

1 个答案:

答案 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>

通过要求另一个模式文档,将有关模式文档的物理位置的信息分离到单个驱动程序文件中会使问题在短期内变得复杂。但它避免了一些令人讨厌的问题,当你想稍后改变一些事情时会出现这些问题。