XSD验证 - 任何在序列(“唯一粒子属性”)

XSD验证 - 任何在序列(“唯一粒子属性”)

问题描述:

我有以下XSD架构:XSD验证 - 任何在序列(“唯一粒子属性”)

<xsd:schema xmlns="http://www.mynamespace.test/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.mynamespace.test/" elementFormDefault="qualified" attributeFormDefault="unqualified"> 
    <xsd:include schemaLocation="../Components.xsd"/> 
    <xsd:element name="PO" type="POType"/> 
    <xsd:complexType name="POType"> 
     <xsd:sequence> 
      <xsd:element ref="PA" maxOccurs="unbounded"/> 
      <xsd:element ref="PB" maxOccurs="unbounded"/> 
      <xsd:any minOccurs="0" /> 
     </xsd:sequence> 
     <xsd:attributeGroup ref="SomeAttrGroup"/> 
     <xsd:attributeGroup ref="SomeOtherAttrGroup"/> 
    </xsd:complexType> 
</xsd:schema> 

在哪里我基本上要确保我的PO元素包含PA元素和PB元素(PA前PB),其中有任何种类的元素允许在PA前面,在PA和PB之间以及PB之后......我尝试在所有这些地方添加xsd:any,但即使只有其中一个是不可能的因为“唯一粒子归因”。

我明白为什么会产生一个错误(无法区分现有的PB元素属于ANY部分还是属于序列中的实际PB)。但是我看不出如何实现我真正想要的东西:是否有可能完成?它将如何完成?

PS:ANY元素可以与PA和PB元素位于同一名称空间中,而不是PA/PB元素本身。

事实证明,在XSD 1.0中这是不可能的,我进一步调查了XSD 1.1的功能。

我想感谢kjhughes的回答(虽然有效,但在大量序列时不太友好),并指出我的方向正确,但事实证明,XSD 1.1具有一些特别设计的这种行为:

OpenContents(参见:XML Schema 1.1, Part 3: An introduction to XML Schema 1.1和这个答案在这里:How to ignore the validation of unknown tags

要允许未知的元素,您可以在复杂类型使用Open Content

<xsd:complexType name="CatalogEntry"> 
    <xsd:openContent mode="interleave"> 
     <xsd:any namespace="##any" processContents="skip"/> 
    </xsd:openContent> 

    <xsd:sequence> 
     <xsd:element name="artist" type="xsd:string"/> 
     <xsd:element name="album" type="xsd:string"/> 
     <xsd:element name="price" type="xsd:decimal"/> 
     <xsd:element name="release_date" type="xsd:dateTime"/> 
    </xsd:sequence> 
    <xsd:attribute name="id" type="xsd:string"/> 
</xsd:complexType> 

指定模式interleave以允许未知元素之间的任何地方,或suffix只允许在序列的端部元件。

还有为一个整体架构指定defaultOpenContent选项:

<xsd:schema ...> 
    ... 
    <xsd:defaultOpenContent mode="interleave"> 
     <xsd:any namespace="##any" processContents="skip"/> 
    </xsd:defaultOpenContent> 
    ... 
    <xsd:complexType name="CatalogEntry"> 
     <xsd:sequence> 
      <xsd:element name="artist" type="xsd:string"/> 
      <xsd:element name="album" type="xsd:string"/> 
      <xsd:element name="price" type="xsd:decimal"/> 
      <xsd:element name="release_date" type="xsd:dateTime"/> 
     </xsd:sequence> 
     <xsd:attribute name="id" type="xsd:string"/> 
    </xsd:complexType> 
    <xsd:element name="cd" type="tns:CatalogEntry"/> 
    ... 
</xsd:schema> 

在哪里我基本上要确保我的PO元素包含PA 元素和PB元素(PB之前PA),那里有允许在PA前面任何 元素,在PA之间PB和后 PB ...

你不能做到这一点的XSD 1.0,但你可以做到这一点的XSD 1.1,因为它的轻松唯一粒子属性要求:

<xsd:schema xmlns="http://www.mynamespace.test/" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      targetNamespace="http://www.mynamespace.test/" 
      elementFormDefault="qualified" 
      attributeFormDefault="unqualified" 
      xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" 
      vc:minVersion="1.1"> 
    <xsd:include schemaLocation="../Components.xsd"/> 
    <xsd:element name="PO" type="POType"/> 
    <xsd:complexType name="POType"> 
     <xsd:sequence> 
      <xsd:any minOccurs="0" /> 
      <xsd:element ref="PA" maxOccurs="unbounded"/> 
      <xsd:any minOccurs="0" /> 
      <xsd:element ref="PB" maxOccurs="unbounded"/> 
      <xsd:any minOccurs="0" /> 
     </xsd:sequence> 
     <xsd:attributeGroup ref="SomeAttrGroup"/> 
     <xsd:attributeGroup ref="SomeOtherAttrGroup"/> 
    </xsd:complexType> 
</xsd:schema> 
+0

非常感谢。在为Java找到一个实际运行的XSD 1.1实现方面遇到了一些麻烦,但它最终提供了预期的结果。 – CounterFlame