La formulación alternativa de la cuestión añadido en una edición posterior parece ser todavía sin respuesta: ¿cómo especificar que entre los hijos de un elemento, tiene que haber uno llamado child3
, uno llamado child4
, y cualquier número llamado child1
o child2
, sin restricción en el orden en que aparecen los niños.
Este es un lenguaje regular definible directamente, y el modelo de contenido que necesita es isomorfo a una expresión regular que define el conjunto de cadenas en el que los dígitos '3' y '4' ocurren exactamente una vez, y los dígitos '1 'y' 2 'ocurren varias veces. Si no es obvio cómo escribir esto, puede ser útil pensar en qué tipo de máquina de estados finitos construirá para reconocer dicho lenguaje. Sería tener al menos cuatro estados distintos:
- un estado inicial en el que ni '3' ni '4' se ha visto
- un estado intermedio en el que '3' se ha visto, pero no '4'
- un estado intermedio en el que '4' se ha visto, pero no '3'
- un estado final en el que tanto '3' y '4' se han visto
Independientemente del estado en el autómata está en, '1' y '2' pueden leerse; ellos no cambian el estado de la máquina. En el estado inicial, también se aceptarán '3' o '4'; en los estados intermedios, solo se acepta "4" o "3"; en el estado final, ni '3' ni '4' son aceptados. La estructura de la expresión regular es más fácil de entender si en primer lugar definir una expresión regular para el subconjunto de nuestro idioma en el que sólo '3' y '4' se producen:
(34)|(43)
Para permitir '1' o '2' Para que se produzca cualquier número de veces en una ubicación determinada, podemos insertar (1|2)*
(o [12]*
si nuestro lenguaje regex acepta esa notación). La inserción de esta expresión en todos los lugares disponibles, obtenemos
(1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)*
Traduciendo esto en un modelo de contenido es sencillo. La estructura básica es equivalente a la expresión regular (34)|(43)
:
<xsd:complexType name="paul0">
<xsd:choice>
<xsd:sequence>
<xsd:element ref="child3"/>
<xsd:element ref="child4"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element ref="child4"/>
<xsd:element ref="child3"/>
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
Inserción de un cero o más opciones de child1
y child2
es sencillo:
<xsd:complexType name="paul1">
<xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
<xsd:choice>
<xsd:sequence>
<xsd:element ref="child3"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
<xsd:element ref="child4"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element ref="child4"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
<xsd:element ref="child3"/>
</xsd:sequence>
</xsd:choice>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
Si queremos minimizar el volumen un poco, puede definir un grupo llamado así por las opciones de repetición de child1
y child2
:
<xsd:group name="onetwo">
<xsd:choice>
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="paul2">
<xsd:sequence>
<xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
<xsd:choice>
<xsd:sequence>
<xsd:element ref="child3"/>
<xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="child4"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element ref="child4"/>
<xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="child3"/>
</xsd:sequence>
</xsd:choice>
<xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
En XSD 1.1, algunas de las limitaciones de all
-grupos se han levantado, por lo que es posible definir este modelo de contenido de manera más concisa:
<xsd:complexType name="paul3">
<xsd:all>
<xsd:element ref="child1" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="child2" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="child3"/>
<xsd:element ref="child4"/>
</xsd:all>
</xsd:complexType>
Pero como se puede ver en los ejemplos dados anteriormente, estos cambios a all
-grupos hacer de hecho, no cambian el poder expresivo del lenguaje; solo hacen más sucinta la definición de ciertos tipos de idiomas.
básicamente sí, estoy buscando elementos child1, child2 a aparecer en cualquier orden, cualquier número de veces .. la respuesta que ha proporcionado aquí sólo funciona para un solo elemento, ¿verdad? ¿o esto resuelve mi requisito también? – jvtech
El esquema en su pregunta cumple con su requisito; el esquema alternativo en mi respuesta es para un solo elemento. ¡Espero que eso lo aclare! :) – xcut
@Pavel, @xcut, Gracias por aclarar, ver el requisito editado ... ¿Alguna idea? – jvtech