2009-05-08 16 views
25

Estoy definiendo un elemento de usuario con XSD. Para este ejemplo, un usuario tiene un nombre, correo electrónico y una o más nacionalidades. Lo he intentado:Camino medio entre XSD todo y secuencia XSD

<xs:all> 
    <xs:element name="name" blabla /> 
    <xs:element name="email" blabla /> 
    <xs:element name="nationality" minOccurs="1" maxOccurs="unbounded" /> 
</xs:all> 

Sin embargo, eso es ilegal. Aparentemente, los elementos dentro de un "Todo" solo pueden aparecer una vez (o no aparecer). Podría solucionar esto cambiando el Todo a una secuencia, pero las personas tendrían que ingresar las propiedades en el orden exacto, lo cual realmente no me importa.

¿Hay una combinación de estos dos disponibles? No de acuerdo con http://www.w3schools.com/Schema/schema_complex_indicators.asp, pero tal vez esté oculto (o mis ojos inexpertos no lo vean).

Por intuición, también probé:

<xs:all> 
    <xs:element name="name" blabla /> 
    <xs:element name="email" blabla /> 
    <xs:sequence> 
    <xs:element name="nationality" minOccurs="1" maxOccurs="unbounded" /> 
    </xs:sequence> 
</xs:all> 

Pero eso es por desgracia no válido.


Aquí es la corriente, real, pieza de XSD:

<!-- user --> 
    <xs:complexType name="user"> 
    <xs:sequence> 
     <xs:element name="firstname" type="xs:string" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="appendix" type="xs:string" minOccurs="0" maxOccurs="1" /> 
     <xs:element name="lastname" type="xs:string" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="address" type="xs:string" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="zipcode" type="xs:string" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="city" type="xs:string" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="username" type="xs:string" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="email" type="xs:string" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="country" type="country" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="nationality" type="xs:string" minOccurs="1" maxOccurs="unbounded"/> 
    </xs:sequence> 
    </xs:complexType> 

Respuesta

3

Su código debe ser válido en XSD 1.1. Para XSD 1.0, debe encontrar una solución alternativa.

+26

¿Cómo utiliza, promulga, opta, crea, encubierta, migra, instancia, encuentra o realiza XSD 1.1? –

+3

¿Podría citar la diferencia entre XSD 1.1 y XSD 1.0 que lo hace válido en 1.1 y no válido en 1.0? –

+0

En la especificación 1.1 no veo ninguna mención de ninguna restricción que haga que el XML del OP sea ilegal. Tristemente, no puedo encontrar la especificación 1.0 para poder comparar. Supongo que tendrías que verificar la versión en las librerías que analizará tu XML/XSD para saber si necesitas cualquiera de los trucos a continuación. –

21

Podría usted acaba de dar vuelta a su thingie "nacionalidad" en su propio tipoCompuesto y luego usar ese nuevo tipo complejo dentro de sus xs: todos ?

<xs:complexType name="NationalityType"> 
    <xs:sequence> 
    <xs:element name="nationality" minOccurs="1" maxOccurs="unbounded" /> 
    </xs:sequence> 
</xs:complexType> 

<xs:all> 
    <xs:element name="name" blabla /> 
    <xs:element name="email" blabla /> 
    <xs:element name="nationalities" type="NationalityType" /> 
</xs:all> 

no tengo nada a mano para probar esto, así que esto es realmente justo al lado de la parte superior de mi cabeza ..... darle una oportunidad!

EDIT: probado por ahora - que funciona, la única menor precio a pagar es que el código XML tendrá que ser algo como esto:

<....> 
    <email>......</email> 
    <nationalities> 
    <nationality>ABC</nationality> 
    <nationality>CDE</nationality> 
    </nationalities> 
    <name>.....</name> 
</.....> 

para que pueda obtener un nodo adicional que contendrá la arbitraria lista larga de <nationality> artículos.

Marc

+4

Esta respuesta es la única correcta. Lo que necesitas es una matriz de nacionalidad. Todos los demás métodos son solo hacks que rompen los principios de XML. –

0

O, ya que "USUARIO" se establecerá con múltiples elementos secundarios, por qué no configurarlo como un tipo complejo? Algo como esto debería funcionar.

<xs:complexType> 
    <xs:sequence> 
    <xs:element name="Name" type="xs:string" /> 
    <xs:element name="Password" type="xs:string" /> 
    <xs:element minOccurs="1" maxOccurs="unbounded" name="Nationality" type="xs:string" /> 
    </xs:sequence> 
</xs:complexType> 
+1

Ya es un tipo complejo. He agregado el XSD real a la pregunta, para que pueda verlo también :) –

0

xs:choice ¿no funciona? Si no, simplemente envuelve eso en una secuencia o viceversa.

+0

¿Eh? ¿Cómo ayudaría eso? Por favor dé un ejemplo. –

7

Creo que lo que estás buscando iría en contra de la intención de XML. Sería parece extraño tener un fragmento XML válido como esto:

<user> 
    <nationality/> 
    <name/> 
    <nationality/> 
    <email/> 
    <nationality/> 
</user> 

Parece que usted está pidiendo algo parecido a lo marc_s propuesta:

<user> 
    <name/> 
    <email/> 
    <nationality/> 
    <nationality/> 
    <nationality/> 
<user> 

que necesita para conseguir empujados a:

<user> 
    <name/> 
    <email/> 
    <nationalities> 
    <nationality/> 
    <nationality/> 
    <nationality/> 
    </nationalities> 
<user> 
1

Para XSD 1.0 funciona la sugerencia de leppie.

El XSD

<?xml version='1.0' encoding='UTF-8'?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name='user'> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="name" type="xs:string" /> 
     <xs:element name="email" type="xs:string" /> 
     <xs:choice minOccurs='0' maxOccurs='unbounded'> 
      <xs:element name="nationality" /> 
     </xs:choice> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

Un documento XML de ejemplo que valida contra el esquema

<user> 
    <name>Name</name> 
    <email>[email protected]</email> 
    <nationality>Italian</nationality> 
    <nationality>Japanese</nationality> 
    <nationality>Alien</nationality> 
</user> 

y validación por ejemplo, utilizando xmllint

xmllint --noout --schema test.xsd test.xml 
test.xml validate 
+0

No hay necesidad de 'elección' en el ejemplo que ha proporcionado. En la medida en que use el elemento 'secuencia' dentro, puede tener maxOccurs = "unbounded". Pero la secuencia impone el orden de los elementos en el interior: ese fue el problema en la pregunta inicial. –

+0

En una nota positiva, esta respuesta muestra que los elementos del grupo modelo 'all',' sequence' y 'choice' se pueden anidar. De forma similar, en 1.1 al menos, los grupos pueden definirse y referirse a ellos, ver http://www.w3.org/TR/xmlschema11-1/#cModel_Group_Definitions que evitarían agregar un nuevo elemento 'contenedor' como lo hace la respuesta de marc_s. –

20

Solo tiene que venir a través del un problema similar (que quería tener cualquier número de cada elemento en cualquier orden) y lo resolvió con una secuencia de opciones. Usando el ejemplo anterior:

<?xml version='1.0' encoding='UTF-8'?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name='user'> 
    <xs:complexType> 
     <xs:sequence minOccurs="0" maxOccurs="unbounded"> 
     <xs:choice> 
      <xs:element name="name" type="xs:string" /> 
      <xs:element name="email" type="xs:string" /> 
      <xs:element name="nationality" /> 
     </xs:choice> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

Esto le permite tener cualquier número de nombre, correo electrónico y nacionalidad en cualquier orden.

+6

Sin embargo, esto permitiría múltiples elementos dentro de ? –