Схема XML Как ограничить атрибут перечислением
У меня есть следующий тег XML
<price currency="euros">20000.00</price>
Как ограничить атрибут валюты одним из следующих:
- евро
- фунты стерлингов
- долларов
И цена на двоих?
Я просто получаю сообщение об ошибке, когда пытаюсь ввести оба типа, вот что у меня получилось:
<xs:element name="price">
<xs:complexType>
<xs:attribute name="currency" type="xs:string">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="pounds" />
<xs:enumeration value="euros" />
<xs:enumeration value="dollars" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
4 ответа
Кажется, что числовое значение отсутствует в вашем определении цены. Попробуйте следующее:
<xs:simpleType name="curr">
<xs:restriction base="xs:string">
<xs:enumeration value="pounds" />
<xs:enumeration value="euros" />
<xs:enumeration value="dollars" />
</xs:restriction>
</xs:simpleType>
<xs:element name="price">
<xs:complexType>
<xs:extension base="xs:decimal">
<xs:attribute name="currency" type="curr"/>
</xs:extension>
</xs:complexType>
</xs:element>
Новый ответ на старый вопрос
Ни один из существующих ответов на этот старый вопрос не решает реальную проблему.
Настоящая проблема заключалась в том, что xs:complexType
не может напрямую иметь xs:extension
как ребенок в XSD. Исправление заключается в использовании xs:simpleContent
первый. Подробности следуют...
Ваш XML,
<price currency="euros">20000.00</price>
будет действителен для любого из следующих исправленных XSD:
Локально определенный тип атрибута
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="price">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="currency">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="pounds" />
<xs:enumeration value="euros" />
<xs:enumeration value="dollars" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>
Глобально определенный тип атрибута
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="currencyType">
<xs:restriction base="xs:string">
<xs:enumeration value="pounds" />
<xs:enumeration value="euros" />
<xs:enumeration value="dollars" />
</xs:restriction>
</xs:simpleType>
<xs:element name="price">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="currency" type="currencyType"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>
Заметки
- Как прокомментировал @Paul, они меняют тип контента
price
отxs:string
вxs:decimal
, но это не является строго необходимым и не было настоящей проблемой. - Отвечая @ user998692, вы можете выделить определение валюты и изменить его на
xs:decimal
Но это тоже не было настоящей проблемой.
Настоящая проблема заключалась в том, что xs:complexType
не может напрямую иметь xs:extension
как ребенок в XSD; xs:simpleContent
нужен в первую очередь.
Связанный вопрос (который не задавался, но, возможно, запутал другие ответы):
Как мог price
быть ограниченным, учитывая, что у него есть атрибут?
В этом случае, отдельное, глобальное определение priceType
будет необходимо; это невозможно сделать только с помощью локальных определений типов.
Как ограничить содержимое элемента, когда элемент имеет атрибут
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="priceType">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="0.00"/>
<xs:maxInclusive value="99999.99"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="price">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="priceType">
<xs:attribute name="currency">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="pounds" />
<xs:enumeration value="euros" />
<xs:enumeration value="dollars" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>
Вам нужно создать тип и сделать атрибут этого типа:
<xs:simpleType name="curr">
<xs:restriction base="xs:string">
<xs:enumeration value="pounds" />
<xs:enumeration value="euros" />
<xs:enumeration value="dollars" />
</xs:restriction>
</xs:simpleType>
затем:
<xs:complexType>
<xs:attribute name="currency" type="curr"/>
</xs:complexType>
<xs:element name="price" type="decimal">
<xs:attribute name="currency" type="xs:string" value="(euros|pounds|dollars)" />
</element>
Это полностью исключило бы необходимость перечисления. Вы можете изменить тип, чтобы удвоить, если требуется.