XSD - 子元素取决于属性值

时间:2009-01-13 16:23:37

标签: xml xsd

我正在尝试为以下XML创建XSD架构:

<root>
  <!-- The actual file must contain one of the following constraints -->
  <constraint type="interval">
    <min>100</min>
    <max>200</max>
  </constraint>

  <constraint type="equals">
    <value>EOF</value>
  </constraint>
</root>

约束元素的子元素取决于type属性的值。

我使用定义type属性的抽象类型和定义子元素的两种扩展类型成功验证了XML。这需要我用xsi:type属性来装饰XML,命名实际的扩展类型:

  <constraint type="interval" xsi:type="intervalConstraintType">
    <min>100</min>
    <max>200</max>
  </constraint>

可悲的是,我无法控制XML结构,并且很难引入新属性。

这对XSD有用吗?是否有更合适的替代品?

2 个答案:

答案 0 :(得分:0)

我认为这应该是可能的,但我目前不知道如何自己做。作为一种解决方法,您可以动态重写xml以包含扩展名。

编辑:嗯,看起来它是不可能的,至少在XSD 1.0中不可能

答案 1 :(得分:0)

  

约束元素的子元素取决于type属性的值。

我认为使用XST 1.1可以使用断言。 您的架构看起来像这样(未经测试)

<!-- ... -->
<xs:element name="constraint"> 
  <xs:complexType> 
     <xs:sequence> 
         <xs:element name="min" type="xs:decimal" minOccurs="0" maxOccurs="1" /> 
         <xs:element name="max" type="xs:decimal" minOccurs="0" maxOccurs="1" />
         <xs:element name="value" type="xs:string"minOccurs="0" maxOccurs="1" />
     </xs:sequence> 
     <xs:attribute name="type" type="contraintType" />

     <xs:assert test="

        if (@type eq 'equals')
        then (exist(value) and empty(min, max))
        else (exist(min) and exist(max) and empty(value))

     "/>

</xs:complexType> 
</xs:element>

<xs:simpleType name="contraintType">
    <xs:restriction base="xs:string">
        <xs:enumeration value="interval"/>
        <xs:enumeration value="equals"/>
    </xs:restriction>
</xs:simpleType>