las - que son los elementos vacios xml
Esquema XML Cómo restringir atributo por enumeración (4)
Tengo la siguiente etiqueta XML
<price currency="euros">20000.00</price>
¿Cómo restrinjo el atributo de moneda a uno de los siguientes?
- euros
- libras
- dólares
Y el precio a un doble?
Acabo de recibir un error cuando intento un tipo en ambos, esto es lo que tengo hasta ahora:
<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>
Nueva respuesta a la vieja pregunta
Ninguna de las respuestas existentes a esta pregunta anterior aborda el problema real.
El verdadero problema era que xs:complexType
no puede tener directamente una xs:extension
como un niño en XSD. La solución es usar xs:simpleContent
primero. Los detalles siguen ...
Tu XML,
<price currency="euros">20000.00</price>
será válido contra cualquiera de los siguientes XSD corregidos:
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
- Como comentó @Paul , estos cambian el tipo de contenido del
price
dexs:string
axs:decimal
, pero esto no es estrictamente necesario y no fue el problema real. - Como respondió @ user998692 , podría separar la definición de moneda, y podría cambiar a
xs:decimal
, pero este tampoco era el problema real.
El verdadero problema era que xs:complexType
no podía tener directamente una xs:extension
como un niño en XSD; xs:simpleContent
es necesario primero.
Un asunto relacionado (que no se preguntó pero puede haber confundido otras respuestas):
¿Cómo se puede restringir el price
dado que tiene un atributo?
En este caso, se necesitaría una definición global separada de priceType
; no es posible hacer esto solo con definiciones de tipos locales.
Cómo restringir el contenido del elemento cuando el elemento tiene un 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>
El valor numérico parece estar ausente de su definición de precio. Pruebe lo siguiente:
<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>
necesitas crear un tipo y crear el atributo de ese 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>
entonces:
<xs:complexType>
<xs:attribute name="currency" type="curr"/>
</xs:complexType>
<xs:element name="price" type="decimal">
<xs:attribute name="currency" type="xs:string" value="(euros|pounds|dollars)" />
</element>
Esto eliminaría por completo la necesidad de enumeración. Puede cambiar el tipo a doble si es necesario.