Eu tenho a seguinte tag XML
<price currency="euros">20000.00</price>
Como posso restringir o atributo de moeda a um dos seguintes:
- euros
- libras
- dólares
E o preço para um duplo?
Acabei de receber um erro quando tento digitar em ambos. Aqui está o que descobri até agora:
<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>
Respostas:
O valor numérico parece estar faltando em sua definição de preço. Experimente o seguinte:
<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>
fonte
<xs:extension
não pode ser diretamente filho de,<xs:complexType
mas também deve estar contido por um<xs:complexContent
ou<xs:simpleContent
.Nova resposta para a velha pergunta
Nenhuma das respostas existentes para esta velha questão aborda o problema real.
O verdadeiro problema é que
xs:complexType
não é possível terxs:extension
um filhodiretamenteno XSD. A solução é usarxs:simpleContent
primeiro. Detalhes a seguir ...Seu XML,
<price currency="euros">20000.00</price>
será válido em qualquer um dos seguintes XSDs corrigidos:
Tipo de atributo definido localmente
<?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>
Tipo de atributo definido globalmente
<?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>
Notas
price
a partirxs:string
dexs:decimal
, mas isso não é estritamente necessário e não era o problema real.xs:decimal
, mas esse também não era o problema real.O verdadeiro problema é que
xs:complexType
não podemos terxs:extension
um filho diretamente no XSD;xs:simpleContent
é necessário primeiro.Um assunto relacionado (que não foi perguntado, mas pode ter confundido outras respostas):
Como poderia
price
ser restringido dado que tem um atributo?Neste caso, uma definição global separada de
priceType
seria necessária; não é possível fazer isso apenas com definições de tipo local.Como restringir o conteúdo do elemento quando o elemento tem atributo
<?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>
fonte
você precisa criar um tipo e tornar o atributo desse tipo:
<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>
então:
<xs:complexType> <xs:attribute name="currency" type="curr"/> </xs:complexType>
fonte
<xs:element name="price" type="decimal"> <xs:attribute name="currency" type="xs:string" value="(euros|pounds|dollars)" /> </element>
Isso eliminaria a necessidade de enumeração completamente. Você pode alterar o tipo para duplo, se necessário.
fonte
@value
não pode aparecerxs:attribute
.xs:attribute
não pode aparecer como filho dexs:element
. Osxs:
prefixos de namespace necessários são omitidos. Esta resposta é uma bagunça e deveria apenas ser excluída.