【问题标题】:Ignore order of elements using xs:extension使用 xs:extension 忽略元素的顺序
【发布时间】:2011-02-10 23:41:01
【问题描述】:

如何设计我的 xsd 以忽略元素序列?

<root> <a/> <b/> </root>

<root> <b/> <a/> </root>

出于代码生成原因,我需要使用extension,所以我尝试了以下使用all

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.example.com/test"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:t="http://www.example.com/test" >

    <xs:complexType name="BaseType">
        <xs:all>
            <xs:element name="a" type="xs:string" />
        </xs:all>
    </xs:complexType>

    <xs:complexType name="ExtendedType">
        <xs:complexContent>
            <xs:extension base="t:BaseType">
                <xs:all> <!-- ERROR -->
                    <xs:element name="b" type="xs:string" />
                </xs:all>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="root" type="t:ExtendedType"></xs:element>
</xs:schema>

虽然这个xsd无效,&lt;!-- ERROR --&gt;报错如下:

cos-all-limited.1.2:一个所有模型组必须出现在一个粒子中,且{min发生} = {max发生} = 1,并且该粒子必须是构成的 {content type} 对的一部分一个复杂的类型定义。

cos-all-limited.1.2 的文档说:

1.2 粒子的 {term} 属性,{max 出现}=1,它是构成复杂类型定义的 {content type} 的一对的一部分。

我不太明白这个(xsd 和英语母语都不是 :))。


我是在做错事,是在做错事,还是没有办法做到这一点?

【问题讨论】:

    标签: xml xsd


    【解决方案1】:

    这里是限制的解释: http://marc.info/?l=xerces-j-user&m=118712527901786&w=4

    您可以使用“全部”模型对复杂类型进行的唯一扩展是添加一些属性。您不能使用新元素进行扩展。

    就我而言,我做过类似的事情:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema targetNamespace="http://www.example.com/test"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:t="http://www.example.com/test" >
    
        <xs:complexType name="BaseType">
            <xs:all>
                <xs:element name="a" type="xs:string" />
            </xs:all>
        </xs:complexType>
    
        <xs:complexType name="ExtendedType">
            <xs:all>
                <xs:element name="a" type="xs:string" /> <!-- copy/paste from BaseType -->
                <xs:element name="b" type="xs:string" />
            </xs:all>
        </xs:complexType>
    
        <xs:element name="root" type="t:ExtendedType"></xs:element>
    </xs:schema>
    

    【讨论】:

      【解决方案2】:

      <xs:complexType name="BaseType"> 
          <xs:sequence> 
              <xs:element name="a" type="xs:string" /> 
          </xs:sequence> 
      </xs:complexType> 
      
      <xs:complexType name="ExtendedType"> 
          <xs:complexContent> 
              <xs:extension base="t:BaseType"> 
                  <xs:sequence> 
                      <xs:element name="b" type="xs:string" /> 
                  </xs:sequence> 
              </xs:extension> 
          </xs:complexContent> 
      </xs:complexType> 
      
      <xs:element name="root" type="t:ExtendedType"></xs:element> 
      

      【讨论】:

      • @Ruslan:你试过这个吗?它将在b 之前强制执行a 的序列,所以它实际上并没有帮助我......
      【解决方案3】:

      主要编辑最初我错过了您需要使用xsd:extension的要求。请注意,xsd:extension 的工作方式与 xsd:sequence 具有基本类型的内容后跟扩展类型的内容一样。正如 XML Schema Primer 所说:

      当一个复杂类型派生于 扩展,其有效的内容模型 是基本类型的内容模型 加上指定的内容模型 类型推导。此外,该 两个内容模型被视为两个 顺序组的孩子。

      因此,实现这项工作的唯一方法似乎是拥有一个空的基本类型并将整个替代项存储在扩展类型中,反之亦然(基本类型中的所有内容和一个空扩展名)。像这样:

      <xsd:complexType name="ExtendedType">
         <xsd:complexContent>
            <xsd:extension base="BaseType">
               <xsd:choice>
                  <xsd:sequence>
                     <xsd:element name="a" type="xsd:string"/>
                     <xsd:element name="b" type="xsd:string"/>
                  </xsd:sequence>
                  <xsd:sequence>
                     <xsd:element name="b" type="xsd:string"/>
                     <xsd:element name="a" type="xsd:string"/>
                  </xsd:sequence>
               </xsd:choice>
            </xsd:extension>
         </xsd:complexContent>
      </xsd:complexType>
      
      <xsd:complexType name="BaseType"/>
      
      <xsd:element name="root" type="ExtendedType"/>
      

      【讨论】:

      • 感谢您的更新。不幸的是,我需要在基本类型中定义一些元素,而在扩展中定义一些元素,所以除非有其他方法,否则扩展类型的元素将始终必须放在基本类型的元素之后......
      • @Peter 在这种情况下,由于“两个内容模型被视为顺序组的两个孩子”,因此(据我所知)无法忽略该顺序。
      • 我已经假设...也许其他人有任何想法,否则我将坚持我的解决方案并强制元素的“正确”顺序。感谢您的宝贵时间,非常感谢!
      • 是的,但如果我有更多的元素,我怎么能写这个?
      • @Bolo 所以你必须按自己的顺序列出所有可能的元素排序?如果你有 5 个元素,你必须定义所有 120 个序列??
      猜你喜欢
      • 2012-10-12
      • 1970-01-01
      • 2022-07-31
      • 1970-01-01
      • 2023-03-21
      • 2018-08-16
      • 2016-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多