【问题标题】:JIBX: How to use more than one target namespace?JIBX:如何使用多个目标命名空间?
【发布时间】:2012-08-20 10:17:35
【问题描述】:

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

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

【问题讨论】:

    标签: xml namespaces xsd jibx


    【解决方案1】:

    是的,这是可能的。这是 XSD 旨在处理的核心场景之一。

    (1) 为每个涉及的命名空间编写单独的架构文档,该命名空间作为xs:schema 元素的targetNamespace 给出。

    如果您的 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>
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-20
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多