Ограничить использование атрибута в утверждении XSD

Учитывая XSD:

<xs:element name="color">
    <xs:complexType>
        <xs:attribute name="type">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:enumeration value="white"/>
                    <xs:enumeration value="black"/>
                    <xs:enumeration value="red"/>
                    <xs:enumeration value="green"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="number" use="optional/>
    </xs:complexType>
</xs:element>

Как бы я написал утверждение так, чтобы

  1. если <color> имеет @type белый или черный, он также не может иметь @number атрибут и
  2. если <color> имеет @type красный или зеленый, он также должен иметь @number приписывать.

2 ответа

Решение

XSD 1.1

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" 
    elementFormDefault="qualified"
    vc:minVersion="1.1">
    <xs:element name="color">
        <xs:complexType>
            <xs:attribute name="type">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="white"/>
                        <xs:enumeration value="black"/>
                        <xs:enumeration value="red"/>
                        <xs:enumeration value="green"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="number" use="optional"/>
            <xs:assert test="   (@type = ('white','black') and not(@number))
                             or (@type = ('red','green') and @number)"/>
        </xs:complexType>
    </xs:element>
</xs:schema>

(Добавлен этот ответ с опозданием, так как другие вопросы указывают здесь)

Другое решение XSD 1.1 здесь заключается в использовании альтернатив типа:

      <xs:element name="color" type="colorType">
  <xs:alternative test="@type = ('white', 'black')" type="color-without-number"/>
  <xs:alternative test="@type = ('red', 'green')" type="color-with-number"/>
</xs:element>

<xs:complexType name="colorType">
  <xs:attribute name="type" .../>
</xs:complexType>

<xs:complexType name="color-without-number">
  <xs:restriction base="colorType">
    ...
  </xs:restriction>
</xs:complexType>

<xs:complexType name="color-with-number">
  <xs:restriction base="colorType">
    ...
  </xs:restriction>
</xs:complexType>

Потенциальное преимущество использования альтернатив типов над утверждениями заключается в том, что реализация с большей вероятностью будет потоковой (то есть проверка не требует построения дерева документа в памяти). А если вы используете XSLT или XQuery с поддержкой схемы, вы получаете более точную информацию о типах, прикрепленную к узлам.

Другие вопросы по тегам