【问题标题】:Xml schema extension orderXML 架构扩展顺序
【发布时间】:2019-05-15 16:35:56
【问题描述】:

如果我有扩展,如何确保派生元素位于基类元素之前?默认值是相反的。我很想使用all,但我知道这是不可能的。

<xs:complexType name="BaseClass">
  <xs:sequence>
    <xs:element name="foo" type="xs:string/>
    <xs:element name="bar" type="xs:string/>
  </xs:sequence>
</xs:complexType>
<xs:complexType name="DerivedClass">
  <xs:complexContent>
    <xs:extension base="BaseClass">
      <xs:sequence>
        <!-- This makes the order foo, bar, cheese, tomato -->
        <!-- But I need cheese, tomato, foo, bar -->
        <xs:element name="cheese" type="xs:string/>
        <xs:element name="tomato" type="xs:string/>
      </xs:sequence>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>
<xs:element name="BaseClass" type="BaseClass"/>
<xs:element name="DerivedClass" type="DerivedClass" substitutionGroup="BaseClass"/>

我希望被接受的 xml 看起来像这样:

<mylist>
    <BaseClass>
     <foo>lala</foo>
     <bar>lala</bar>
    </BaseClass>
    <DerivedClass>
     <cheese>cheddar</cheese>
     <tomato>red</tomato>
     <foo>lala</foo>
     <bar>lala</bar>
    </DerivedClass>
</mylist>

目前我正在考虑将 BaseClass 的所有元素也复制到 DerivedClass 中,但我不知道替换组会发生什么,什么不会。

【问题讨论】:

    标签: xml inheritance xsd


    【解决方案1】:

    如果我有扩展,如何确保派生元素位于基类元素之前?

    不幸的是,这是不可能的。 扩展 complexType 时,新元素将作为序列添加到基本元素中。 基本上,新的内容模型如下所示:

    (base element model), (extension element model)
    

    这就是 XSD 中类型扩展的工作原理。 你可能想知道为什么? 因为扩展类型必须符合基类型。 你不能有任何东西作为基础的延伸。

    假设您有一个知道如何处理类型 A 元素的软件。 软件可能假设实际上类型 A 可以扩展, 但无论如何,它必须能够在一个应该是 A 类型的元素中找到 它从 A 类型知道/期望的一切......以及 A 类型固有的元素内容 (这是最重要的事情之一)必须放在第一位!

    【讨论】:

    • 那太糟糕了,因为我们的 XmlWriter 一直在反方向写。我不能再改变 XML 了。我决定将所有内容都展平,只从 A 到 Z 重写每个案例而不进行扩展。
    • 也很可惜。在我的情况下,这阻止了对常见元素的分解(替代方法是更新许多现有文档)。
    【解决方案2】:

    解决这个问题的唯一方法是使用组,它可以插入到序列中的任何位置。但是,这种方法不能使用substitutionGroup

    <xs:group name="BaseGroup">
      <xs:sequence>
        <xs:element name="foo" type="xs:string"/>
        <xs:element name="bar" type="xs:string"/>
      </xs:sequence>
    </xs:group>
    <xs:complexType name="BaseClass">
      <xs:group ref="BaseGroup"/>
    </xs:complexType>
    <xs:complexType name="DerivedClass">
      <xs:sequence>
        <xs:element name="cheese" type="xs:string"/>
        <xs:element name="tomato" type="xs:string"/>
        <xs:group ref="BaseGroup"/>
      </xs:sequence>
    </xs:complexType>
    <xs:element name="BaseClass" type="BaseClass"/>
    <xs:element name="DerivedClass" type="DerivedClass"/>
    

    【讨论】:

      【解决方案3】:

      我在验证 PHP 生成的 XML 时遇到了同样的问题。

      This 是我解决它的方法。基本上,

      1. 遍历所有 php 类属性,
      2. 将当前类中的内容推送到一个数组中,
      3. 将父类中的内容推送到另一个数组中。
      4. 将当前类属性合并到父类属性的末尾
      5. 从重新排序的属性数组生成 XML

      【讨论】:

        猜你喜欢
        • 2018-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-03
        • 2014-11-15
        • 2016-12-06
        • 1970-01-01
        相关资源
        最近更新 更多