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>
Odpowiedzi:
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>
źródło
<xs:extension
nie może być bezpośrednio dzieckiem,<xs:complexType
ale zamiast tego musi być również zawarty przez<xs:complexContent
lub<xs:simpleContent
.Nowa odpowiedź na stare pytanie
Żadna z istniejących odpowiedzi na to stare pytanie nie rozwiązuje rzeczywistego problemu.
Prawdziwym problemem było to, że
xs:complexType
nie można bezpośrednio miećxs:extension
dziecka w XSD. Poprawką jest użycie jakoxs:simpleContent
pierwsze. 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
price
zxs:string
naxs:decimal
, ale nie jest to absolutnie konieczne i nie stanowiło prawdziwego problemu.xs:decimal
, ale to też nie był prawdziwy problem.Prawdziwym problemem było to, że
xs:complexType
nie można bezpośrednio miećxs:extension
dziecka w XSD;xs:simpleContent
jest potrzebny jako pierwszy.Powiązana sprawa (która nie została zadana, ale mogła pomieszać inne odpowiedzi):
Jak można
price
było ograniczyć, biorąc pod uwagę, że ma atrybut?W takim przypadku
priceType
potrzebna 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>
źródło
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>
źródło
<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.
źródło
@value
nie może pojawić się naxs:attribute
.xs:attribute
nie może pojawić się jako dzieckoxs:element
. Potrzebnexs:
przedrostki przestrzeni nazw są pomijane. Ta odpowiedź to bałagan i należy ją po prostu usunąć.