Схема XML Как ограничить атрибут перечислением

85

У меня есть следующий тег XML

<price currency="euros">20000.00</price>

Как ограничить атрибут валюты одним из следующих:

  • евро
  • фунты
  • доллары

И цена в два раза больше?

Я просто получаю сообщение об ошибке, когда пытаюсь ввести тип на обоих, вот что у меня пока есть:

<xs:element name="price">
    <xs:complexType>
        <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:complexType>
</xs:element>
Люк
источник
1
Если вы сделаете это, вам также необходимо удалить type = "xs: string" из элемента <xs: attribute>. Вы не можете указать тип, если присутствует simpleType или complexType.
Sal

Ответы:

116

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

<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>
user998692
источник
3
Как ответил @kjhughes, <xs:extensionне может быть напрямую дочерним элементом, <xs:complexTypeно вместо этого также должен содержаться в <xs:complexContentили <xs:simpleContent.
HankCa
22

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

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

Настоящая проблема заключалась в том, что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>
Kjhughes
источник
8

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

<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>
ABCade
источник
Привет, К сожалению, это не позволяет мне одновременно ограничить тип цены «удвоением» И перечислением ограничений для атрибута «валюта»
Люк,
-2
<xs:element name="price" type="decimal">
<xs:attribute name="currency" type="xs:string" value="(euros|pounds|dollars)" /> 
</element> 

Это полностью устранит необходимость в перечислении. При необходимости вы можете изменить тип на двойной.

Начикет Кулкарни
источник
@valueне может появиться xs:attribute. xs:attributeне может быть дочерним по отношению к xs:element. Необходимые xs:префиксы пространства имен опущены. Это беспорядок, и его следует просто удалить.
kjhughes