1

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

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

4

1 回答 1

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定义元素(或属性——我认为您一定已经改变了如何呈现示例的想法)。barbar

(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>

将有关架构文档的物理位置的信息分离到单个驱动程序文件中,在短期内会使事情变得复杂,因为需要另一个架构文档。但它避免了当您稍后想要稍微改变一些东西时出现的许多令人讨厌的问题。

于 2012-08-20T14:46:13.810 回答