Schemat XML Jak ograniczyć atrybut przez wyliczenie

85

Mam następujący tag XML

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

Jak ograniczyć atrybut waluty do jednego z poniższych:

  • euro
  • funtów
  • dolarów

A cena podwoi się?

Po prostu pojawia się błąd, gdy próbuję wpisać tekst na obu, oto co mam do tej pory:

<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>
Łukasz
źródło
1
Jeśli to zrobisz, musisz usunąć również type = "xs: string" z elementu <xs: attribute>. Nie można podać typu, gdy obecny jest simpleType lub complexType.
Sal

Odpowiedzi:

116

Wydaje się, że w definicji ceny brakuje wartości liczbowej. Spróbuj wykonać następujące czynności:

<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
źródło
3
Zgodnie z odpowiedzią @kjhughes, element <xs:extensionnie może być bezpośrednio dzieckiem, <xs:complexTypeale zamiast tego musi być również zawarty przez <xs:complexContentlub <xs:simpleContent.
HankCa
22

Nowa odpowiedź na stare pytanie

Żadna z istniejących odpowiedzi na to stare pytanie nie rozwiązuje rzeczywistego problemu.

Prawdziwym problemem było to, żexs:complexTypenie można bezpośrednio miećxs:extensiondziecka w XSD. Poprawką jest użycie jakoxs:simpleContentpierwsze. Szczegóły poniżej ...


Twój XML,

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

będzie obowiązywał w stosunku do jednego z następujących poprawionych XSD:

Typ atrybutu zdefiniowany lokalnie

<?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>

Globalnie zdefiniowany typ atrybutu

<?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>

Uwagi

  • Jak skomentował @Paul , zmieniają one typ zawartości pricez xs:stringna xs:decimal, ale nie jest to absolutnie konieczne i nie stanowiło prawdziwego problemu.
  • Jak odpowiedział @ user998692 , możesz oddzielić definicję waluty i zmienić na xs:decimal, ale to też nie był prawdziwy problem.

Prawdziwym problemem było to, że xs:complexTypenie można bezpośrednio mieć xs:extensiondziecka w XSD; xs:simpleContentjest potrzebny jako pierwszy.

Powiązana sprawa (która nie została zadana, ale mogła pomieszać inne odpowiedzi):

Jak można pricebyło ograniczyć, biorąc pod uwagę, że ma atrybut?

W takim przypadku priceTypepotrzebna byłaby oddzielna, globalna definicja ; nie można tego zrobić tylko z definicjami typu lokalnego.

Jak ograniczyć zawartość elementu, gdy element ma atrybut

<?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
źródło
8

musisz stworzyć typ i uczynić atrybut tego typu:

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

następnie:

<xs:complexType>
    <xs:attribute name="currency" type="curr"/>
</xs:complexType>
ABCade
źródło
Witam, niestety nie pozwala mi to ograniczyć typu ceny do „podwójnego” ORAZ wyliczenia ograniczeń w atrybucie „currency” w tym samym czasie
Łukasz
-2
<xs:element name="price" type="decimal">
<xs:attribute name="currency" type="xs:string" value="(euros|pounds|dollars)" /> 
</element> 

To całkowicie wyeliminowałoby potrzebę wyliczania. W razie potrzeby możesz zmienić typ na podwojony.

Nachiket Kulkarni
źródło
@valuenie może pojawić się na xs:attribute. xs:attributenie może pojawić się jako dziecko xs:element. Potrzebne xs:przedrostki przestrzeni nazw są pomijane. Ta odpowiedź to bałagan i należy ją po prostu usunąć.
kjhughes