2008-09-19 20 views
18

Estoy intentando configurar parte de un esquema que es como una "Secuencia" donde todos los elementos secundarios son opcionales, pero al menos uno de los elementos debe estar presente, y podría haber más de uno de ellos.Esquema XML para "uno o más de estos elementos pero debe ser al menos uno"

He intentado hacer lo siguiente, pero XMLSpy se queja de que "El modelo de contenido contiene el nombre del elemento elementos < =" DateConstant "> y < element name = "DateConstant" > que no puede ser determinado de forma única.":

<xs:choice> 
     <xs:sequence> 
      <xs:element name="DateConstant"/> 
      <xs:element name="TimeConstant"/> 
     </xs:sequence> 
     <xs:element name="DateConstant"/> 
     <xs:element name="TimeConstant"/> 
    </xs:choice> 

¿Se puede hacer esto (y en caso afirmativo, cómo)?

Algunas aclaraciones: Solo quiero permitir uno de cada elemento con el mismo nombre. Puede haber un "DateConstant" y/o un "TimeConstant", pero no dos de ninguno. La respuesta de Gizmo coincide con mis requisitos, pero no es práctico para una gran cantidad de elementos. La respuesta de Hurst permite dos o más elementos del mismo nombre, que no quiero.

Respuesta

21

Prueba esto:

<xs:choice> 
    <xs:sequence> 
    <xs:element name="Elem1" /> 
    <xs:element name="Elem2" minOccurs="0" /> 
    <xs:element name="Elem3" minOccurs="0" /> 
    </xs:sequence> 
    <xs:sequence> 
    <xs:element name="Elem2" /> 
    <xs:element name="Elem3" minOccurs="0" /> 
    </xs:sequence> 
    <xs:element name="Elem3" /> 
</xs:choice> 

Si lo hace, se fuerza ya sea para elegir el primer elemento y luego el resto es opcional, ya sea el segundo elemento y el resto es opcional, ya sea el tercer elemento.

Esto debería hacer lo que quiera, espero.

Por supuesto, puede colocar las subsecuencias en grupos, para evitar duplicar un elemento en cada secuencia si se da cuenta de que omite una.

13

De acuerdo con el artículo técnico en MSDN titulado entendimiento esquema XML en http://msdn.microsoft.com/en-us/library/aa468557.aspx#understandxsd_topic5 usted puede tomar ventaja de las restricciones tales como minOcurrencias en la definición elección (compositor) misma:

"mediante la restricción de ocurrencia en un compositor se aplica a todo el grupo como un todo "

(Vea el ejemplo más sofisticado que utiliza tipos complejos anidados y el ejemplo AuthorType)

Usted indicó su requisito ya que "al menos uno de los elementos debe estar presente, y podría haber más de uno". Por lo tanto, propongo que pruebe lo siguiente:

<xs:choice minOccurs="1" maxOccurs="unbounded"> 
    <xs:element name="DateConstant" type="..."/> 
    <xs:element name="TimeConstant" type="..."/> 
</xs:choice> 
+0

Esto no funciona. Si un elemento está ausente, mientras el uno está presente, no habrá ningún error. – yegor256

1

@hurst,

Desafortunadamente usted no ha podido entender la pregunta original. Colocar minOccurs = "1" en la elección se cumple automáticamente cuando TODOS los elementos que tienen minOccurs = "0" están contenidos como opciones.

Por lo tanto, no ha contabilizado el "al menos uno" requerido por el póster original, porque ningún elemento satisface correctamente 1 ocurrencia de dos elementos completamente opcionales.

Hasta ahora no puedo encontrar una solución a esto, ya que minOccur/maxOccur se relacionan con el grupo en el que están definidos y NO se relacionan con un número total de nodos.Tampoco puede usar el elemento de opción para definir el mismo elemento nombrado más de una vez o se vuelve "ambiguo". He visto algunos ejemplos que usan referencias en lugar de elementos de un tipo específico, pero creo que esto falla el analizador de microsoft XSD.

<xs:choice minOccurs="1" maxOccurs="1"> 
    <xs:sequence minOccurs="1" maxOccurs="1"> 
    <xs:element name="Elem1" minOccurs="1" maxOccurs="1" /> 
    <xs:element name="Elem2" minOccurs="0" maxOccurs="1" /> 
    </xs:sequence> 
    <xs:sequence > 
    <xs:element name="Elem2" minOccurs="1" maxOccurs="1" /> 
    </xs:sequence> 
</xs:choice> 

Aquí se puede ver que, o bien que tiene la primera secuencia (que debe tener Elem1 pero puede tener Elem2 opcionalmente), o tiene la segunda secuencia (que debe tener Elem2).

Por lo tanto, ahora tiene "uno o más" de estos 2 elementos. Por supuesto, esto se vuelve exponencialmente más complejo cuanto más opciones tenga, ya que necesita proporcionar opciones adicionales para todas las combinaciones posibles.

+1

Solo una objeción: no es "exponencialmente más complejo", solo de forma cuadrática. Pero es engorroso. Ojalá hubiera algo más fácil. – user3697176

Cuestiones relacionadas