Esquema XML Cómo restringir el atributo por enumeración


85

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>

1
Si hace esto, también debe eliminar type = "xs: string" del elemento <xs: attribute>. No puede dar el tipo cuando está presente simpleType o complexType.
Sal

Respuestas:


116

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>

3
Como respondió @kjhughes, <xs:extensionno puede ser directamente un hijo de, <xs:complexTypesino que también debe estar contenido por una <xs:complexContento <xs:simpleContent.
HankCa

22

Nueva respuesta a la pregunta anterior

Ninguna de las respuestas existentes a esta vieja pregunta aborda el problema real.

El verdadero problema era quexs:complexTypeno se puede tener directamentexs:extensionun hijo en XSD. La solución es usarxs:simpleContentprimero. 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 se ha comentado por @ Pablo , éstos hacen cambiar el tipo de contenido pricea partir xs:stringde xs:decimal, pero esto no es estrictamente necesario y no era el verdadero problema.
  • Como respondió @ user998692 , podría separar la definición de moneda y cambiar a xs:decimal, pero este tampoco era el problema real.

El problema real era que xs:complexTypeno se puede tener directamente xs:extensionun hijo en XSD; xs:simpleContentse necesita primero.

Un asunto relacionado (que no se preguntó pero puede haber confundido otras respuestas):

¿Cómo se podría pricerestringir dado que tiene un atributo?

En este caso, priceTypeserí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>

8

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>

Hola, Lamentablemente, esto no me permite restringir el tipo de precio a "duplicar" Y la enumeración de restricción en el atributo "moneda" al mismo tiempo
Lucas

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


@valueno puede aparecer en xs:attribute. xs:attributeno puede aparecer como hijo de xs:element. xs:Se omiten los prefijos de espacio de nombres necesarios . Esta respuesta es un desastre y debería eliminarse.
kjhughes
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.