Определение XSD для проверки групп разрешенных атрибутов XML для одного и того же элемента - PullRequest
0 голосов
/ 12 августа 2010

Я хотел бы определить XSD, который будет проверять следующий XML.

<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' .

Например;

Если атрибут 'name' = "Время ожидания автоматического выключения", то 'type' требуется и можеттолько "целое число" и требуется '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 голосов
/ 31 августа 2010

Никто не ответил на это, я надеюсь, что это все еще интересно для вас.Подходы, которые вы изложили, не работают: XML-схема не может проверять ограничения формы «если элемент X содержит что-то, тогда проверьте Y».Кроме того, вы не можете иметь два элемента с одинаковым именем, но разными типами в одном контейнере, как вы сказали.

Однако вы, что вы можете сделать, это 1) создать дочерний элементв параметре с именем 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...