带有条件属性的XSD

时间:2013-02-15 23:53:20

标签: xml xsd xsd-validation

我想创建一个XSD文件,该文件可以检查某个属性是否存在,而不是基于其父节点的名称。知道我怎么能这样做吗?以下是我想要做的一个例子。

Xml - AttrA和AttrB是必需的,因为父节点是“A”

<A>
 <B AttrA="1" AttrB="2" />
</A>

Xml - AttrB和AttrC是必需的,因为父节点是“C”

<C>
 <B AttrB="2" AttrC="3" />
</C>

1 个答案:

答案 0 :(得分:1)

最简单的方法是将其中一种或两种形式的B局部化为其父类的复杂类型。如果A和C都是顶级元素,并且我们将两种形式的B本地化,例如,您可以写:

<xs:element name="A">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="B" type="B-in-A"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:element name="C">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="C" type="B-in-C"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

B-in-A和B-in-C这两种类型已被声明,但是你喜欢,例如

<xs:complexType name="B-in-A">
  <xs:sequence/>
  <xs:attribute name="AttrA" type="xs:integer"/>
  <xs:attribute name="AttrB" type="xs:integer"/>
</xs:complexType>

<xs:complexType name="B-in-C">
  <xs:sequence/>
  <xs:attribute name="AttrB" type="xs:integer"/>
  <xs:attribute name="AttrC" type="xs:integer"/>
</xs:complexType>

在某些情况下,您可能想要为B声明一个泛型类型,并从中派生出B-in-A和B-in-C这两种类型,以便它们彼此具有某种遗传关系;这取决于你是否有办法利用这种派生关系。

在XSD 1.1中,您还可以选择使用所需的AttrB和可选的AttrA和AttrC声明B,然后对A和C的类型进行断言,以检查A中的B是否携带AttrA而不是AttrC,和C中的B相反。

这些中的哪一个更清晰,更简单可能取决于您是否将B的属性视为(a)基于其上下文的B行为的差异,或(b)对A和/的约束或C,其形式要求为其子女提供特定形式。