XSD:允许来自不同命名空间的元素在序列中的任何位置

时间:2014-08-07 08:58:34

标签: xml xsd

我一直在尝试以下方面。 我想为XML创建一个XSD,其中某些元素只允许出现一次且需要有效,其他名称空间中的元素可以在任何地方使用,并且没有必须验证的模式。

应该允许的XML:

<ns:bookstore>
  <ns:books>
    <ns:book1 />
    <other:magazine1 />
    <ns:book2 />
    <ns:book3 />
    <otherns:newspaper1  />
    <ns:book4 />
  </ns:books>
</ns:bookstore>

book1,2,3和4只能在XML中出现一次并需要进行验证,其他名称空间中的元素则为ns:应该被允许而不进行验证。为此,我在我的XSD中使用xs:any with processContents lax:

 <xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="ns">

<xs:element name="bookstore">
   <xs:complexType>
      <xs:sequence >
        <xs:element name ="book1" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book2" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book3" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book4" type="xs:string" maxOccurs="1"/>
        <xs:any processContents="lax" namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
       </xs:sequence>
    </xs:complexType>
</xs:element>

在此解决方案中,其他命名空间中的元素只能出现在序列之后,而不能出现在必需元素之间。理想的解决方案(但我知道在XSD中不允许)是在xs:all中更改我的xs:sequence(但xs:所有不允许在xs:all中)

我知道有这样的问题,但没有一个答案对我来说很清楚。 有人能为我提供解决这个问题的方法吗?

我也尝试了以下内容:

 <xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="ns">

<xs:element name="bookstore">
   <xs:complexType>
      <xs:choice maxOccurs="unbounded" >
        <xs:element name ="book1" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book2" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book3" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book4" type="xs:string" maxOccurs="1"/>
        <xs:any processContents="lax" namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
       </xs:choice>
    </xs:complexType>
</xs:element>

因为选择中出现无界限,所以选择中的任何元素都可以在任何位置发生任意多次。但是这里的book1,2,3和4可以多次出现,在我的用例中是不允许的。

有人有另一个可能对我有帮助的想法吗?在此先感谢!!

P.S。:我的书的类型实际上是complexTypes,并且彼此不同,这只是XML的简化版本。

修改

我的XSD中不允许这样做:

   <xs:element name="bookstore">
   <xs:complexType>
      <xs:sequence >
        <xs:element name ="book1" type="xs:string" maxOccurs="1"/>
        <xs:any processContents="lax" namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name ="book2" type="xs:string" maxOccurs="1"/>
        <xs:any processContents="lax" namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name ="book3" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book4" type="xs:string" maxOccurs="1"/>
        <xs:any processContents="lax" namespace="##other" minOccurs="0"    maxOccurs="unbounded"/>
       </xs:sequence>
    </xs:complexType>
</xs:element>

1 个答案:

答案 0 :(得分:1)

在XSD 1.1中,您可以通过定义开放内容模型来轻松完成此任务:

<xs:complexType ...>
  <xs:openContent mode="interleave">
    <xs:any namespace=.../>
  </xs:openContent>
  ... regular content model ...
</xs:complexType>

在1.0中没有简单的方法可以做到这一点;你只需要在每个可能的位置放置一个可选的通配符。