Схема XML Как ограничить атрибут перечислением - PullRequest
82 голосов
/ 19 января 2012

У меня есть следующий 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 ]

111 голосов
/ 19 января 2012

Кажется, что числовое значение отсутствует в вашем определении цены.Попробуйте следующее:

<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>
21 голосов
/ 23 октября 2015

Новый ответ на старый вопрос

Ни один из существующих ответов на этот старый вопрос не решает реальную проблему.

Реальная проблема заключалась в том, что 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 1035 *, они изменяют тип содержимого 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>
7 голосов
/ 19 января 2012

вам нужно создать тип и сделать атрибут этого типа:

<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>
0 голосов
/ 30 сентября 2016
<xs:element name="price" type="decimal">
<xs:attribute name="currency" type="xs:string" value="(euros|pounds|dollars)" /> 
</element> 

Это полностью исключило бы необходимость перечисления.Вы можете изменить тип, чтобы удвоить, если требуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...