Tengo la siguiente etiqueta XML
<price currency="euros">20000.00</price>
¿Cómo puedo restringir el atributo de moneda a uno de los siguientes?
- euros
- libras
- dolares
¿Y el precio al doble?
Recibo un error cuando intento escribir en ambos, esto es lo que tengo hasta ahora:
<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>
Respuestas:
El valor numérico parece faltar en su definición de precio. Intente 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>
fuente
<xs:extension
no puede ser directamente un hijo de,<xs:complexType
sino que también debe estar contenido por una<xs:complexContent
o<xs:simpleContent
.Nueva respuesta a la pregunta anterior
Ninguna de las respuestas existentes a esta vieja pregunta aborda el problema real.
El verdadero problema era que
xs:complexType
no se puede tener directamentexs:extension
un hijo en XSD. La solución es usarxs: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
price
a partirxs:string
dexs:decimal
, pero esto no es estrictamente necesario y no era el verdadero problema.xs:decimal
, pero este tampoco era el problema real.El problema real era que
xs:complexType
no se puede tener directamentexs:extension
un hijo en XSD;xs:simpleContent
se necesita primero.Un asunto relacionado (que no se preguntó pero puede haber confundido otras respuestas):
¿Cómo se podría
price
restringir dado que tiene un atributo?En este caso,
priceType
sería necesaria una definición global separada de ; 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>
fuente
necesita crear un tipo y hacer 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>
fuente
<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.
fuente
@value
no puede aparecer enxs:attribute
.xs:attribute
no puede aparecer como hijo dexs:element
.xs:
Se omiten los prefijos de espacio de nombres necesarios . Esta respuesta es un desastre y debería eliminarse.