定义XSD以验证同一元素的允许XML属性组

时间:2010-08-12 15:17:53

标签: xml xsd

我想定义一个验证以下XML的XSD。

<parameters>
    <param name="Maximum Error Threshold" type="integer">10</param>
    <param name="Auto Shutdown Timeout Duration" type="integer" unit="seconds">300</param>
    <param name="Flow Rate Adjusment" type="integer" unit="litrePerSec">0.5</param>
    <param name="Configuration Download Time" type="timeofday" format="timestring">03:20</param>
    <param name="Maximum Issue Value" type="integer" unit="cents" format="numericfloat">145.50</param> 
</parameters>

我目前的架构看起来像是:

  <xs:element name="parameters">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="5" minOccurs="5" ref="param"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="param">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:NMTOKEN">
          <xs:attribute name="name" use="required" type="AttributeNames"/>
          <xs:attribute name="type" use="required" type="AttributeTypes"/>
          <xs:attribute name="format" use="optional" type="AttributeFormats"/>
          <xs:attribute name="unit" use="optional" type="AttributeUnits"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
  <xs:simpleType name="AttributeNames">
    <xs:restriction base="xs:token">
      <xs:enumeration value="Maximum Error Threshold"/>
      <xs:enumeration value="Auto Shutdown Timeout Duration"/>
      <xs:enumeration value="Flow Rate Adjusment"/>
      <xs:enumeration value="Configuration Download Time"/>
      <xs:enumeration value="Maximum Issue Value"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="AttributeTypes">
    <xs:restriction base="xs:NCName">
      <xs:enumeration value="integer"/>
      <xs:enumeration value="timeofday"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="AttributeFormats">
    <xs:restriction base="xs:NCName">
      <xs:enumeration value="timestring"/>
      <xs:enumeration value="numericfloat"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="AttributeUnits">
    <xs:restriction base="xs:NCName">
      <xs:enumeration value="seconds"/>
      <xs:enumeration value="litrePerSec"/>
      <xs:enumeration value="cents"/>
    </xs:restriction>
  </xs:simpleType>

这很有效。但它并没有给我完整的验证。 我想确保'param'元素中存在相应的属性(并且这些属性包含适当的值),具体取决于'name'属性的内容包含。

例如;

如果'名称'属性=“自动关机超时持续时间”,则'类型'是必需的,只能是“整数”且 'unit'是必需的,可以是“小时”,“分钟”或“秒”。

但如果'name' attribute =“Maximum Error Threshold”,那么'type'是必需的,只能是“整数”但'单位'是不允许的。

所以我决定分别描述每个参数;例如:

  <xs:complexType name="MaxErrorParam">
    <xs:simpleContent>
      <xs:extension base="xs:NMTOKEN">
        <xs:attribute name="name" fixed="Maximum Error Threshold"/>
        <xs:attributeGroup ref="CounterParameterAttributes"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>

  <xs:complexType name="AutoShutdownParam">
    <xs:simpleContent>
      <xs:extension base="xs:NMTOKEN">
        <xs:attribute name="name" fixed="Auto Shutdown Timeout Duration"/>
        <xs:attributeGroup ref="TimeOutParameterAttributes"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>

  <xs:attributeGroup name="CounterParameterAttributes">
    <xs:attribute name="type" use="required" fixed="integer"/>
  </xs:attributeGroup>

  <xs:attributeGroup name="TimeOutParameterAttributes">
    <xs:attribute name="type" use="required" fixed="integer"/>
    <xs:attribute name="format" use="required" type="TimeUnitsType"/>
  </xs:attributeGroup>

  <xs:simpleType name="TimeUnitsType">
    <xs:restriction base="xs:NCName">
      <xs:enumeration value="minutes"/>
      <xs:enumeration value="seconds"/>
      <xs:enumeration value="hours"/>
    </xs:restriction>
  </xs:simpleType>

但这意味着我需要定义'param'元素,如下所示;这会导致错误,因为元素'param'被定义为两次,具有不同的类型。

  <xs:element name="parameters">
    <xs:complexType>
      <xs:all>
        <xs:element name="param" type="MaxErrorParam"/>
        <xs:element name="param" type="AutoShutdownParam"/>
        etc...
      </xs:>
    </xs:complexType>
  </xs:element>

任何人都可以提出解决方案或指出我正确的方向吗?

1 个答案:

答案 0 :(得分:0)

没有人回答这个问题,我希望你们仍然感兴趣。您概述的方法不起作用:XML Schema无法验证表单的约束“如果元素X包含某些内容然后检查Y”。此外,正如您所说,您不能在同一个容器中拥有两个名称相同但类型不同的元素。

但是,您可以做的是1)在param中创建一个名为value且类型为xs:anySimpleType的子元素,并且2)使用本机XML模式类型覆盖机制(xsi:type):

<parameters xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <param name="Maximum Error Threshold">
        <value xsi:type="xs:int">10</value>
    </param>
</parameters>