Votre question a une résolution, mais il ne sera pas assez. Voici pourquoi:
Violation de non-déterministe des modèles de contenu
Vous avez déjà touché à l'âme de W3C XML du Schéma. Ce que vous demandez — ordre variable et la variable d'éléments inconnus — viole la plus difficile, mais la plupart des principe de base de XSD, la règle de la Non-Ambiguïté, ou, plus formellement, l' Attribution de Particule Unique Contrainte:
Un modèle de contenu doivent être établies de telle
que lors de la validation [..] chaque élément
dans la séquence peut être unique
déterminé, sans examiner les
le contenu ou les attributs de l'élément,
et sans aucune information sur les
les éléments dans le reste de la
la séquence.
En anglais normal: quand un fichier XML est validé et le XSD processeur de rencontres, <SurName>
il doit être en mesure de valider sans vérifier d'abord si elle est suivie par l' <GivenName>
, c'est à dire, pas de hâte. Dans votre scénario, ce n'est pas possible. Cette règle existe pour permettre des implémentations par des Machines à états Finis, ce qui devrait rendre les implémentations plutôt trivial et rapide.
C'est l'une des plus controversée de questions et est un héritage de SGML et de la DTD (modèles de contenu doit être déterministe) et XML, qui définit, par défaut, que l'ordre des éléments est important (ainsi, en essayant le contraire, la commande sans importance, est dur).
Comme Marc_s déjà suggéré, Relax_NG est une alternative qui permet de modèles de contenu non déterministes. Mais que pouvez-vous faire si vous êtes coincé avec des schémas XML du W3C?
Non-travail semi-valides solutions
Vous avez déjà remarqué qu' xs:all
est très restrictive. La raison en est simple: la même non-déterministe de la règle s'applique et c'est pourquoi, xs:any
, min/maxOccurs
de plus de l'un et de séquences ne sont pas autorisés.
Aussi, vous avez essayé toutes sortes de combinaisons d' choice
, sequence
et any
. L'erreur que Microsoft XSD processeur déclenche lors de la rencontre d'invalide situation est la suivante:
Erreur: Plusieurs définition de l'élément
'http://example.com/Chad:SurName'
causes le modèle de contenu de devenir
ambigu. Un modèle de contenu doit être
formés tels que lors de la validation de
un élément d'information d'élément de la séquence,
les particules contenues directement,
indirectement ou implicitement, y avec
pour tenter de valider chaque élément
dans la séquence, à son tour, peut être
déterminée de manière unique et sans examen
le contenu ou les attributs de l'
item, et sans aucune information
sur les éléments dans le reste de
la séquence.
Dans O'Reilly Schéma XML (oui, le livre a ses défauts) c'est très bien expliqué. Furtunately, les parties de l'ouvrage sont disponibles en ligne. Je vous recommande fortement de lire à travers la section 7.4.1.3 à propos de l' Attribution de Particule Unique Règle, leurs explications et des exemples sont beaucoup plus claire que je ne peux jamais obtenir.
Une solution de travail
Dans la plupart des cas, il est possible de partir d'un undeterministic d'une conception déterministe de la conception. Ce n'est généralement pas l'air joli, mais c'est une solution si vous devez coller avec le W3C XML Schema et/ou si vous devez absolument permettre à des règles strictes à votre XML. Le cauchemar avec votre situation, c'est que vous voulez appliquer une chose (2 éléments prédéfinis) et en même temps envie de l'avoir très lâche (l'ordre n'a pas d'importance et que tout peut aller entre avant et après). Si je ne cherche pas à vous donner de bons conseils, mais juste vous prendre directement à une solution, elle sera comme suit:
<xs:element name="User">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" processContents="lax" namespace="##other" />
<xs:choice>
<xs:sequence>
<xs:element name="GivenName" />
<xs:any minOccurs="0" processContents="lax" namespace="##other" />
<xs:element name="SurName" />
</xs:sequence>
<xs:sequence>
<xs:element name="SurName" />
<xs:any minOccurs="0" processContents="lax" namespace="##other" />
<xs:element name="GivenName" />
</xs:sequence>
</xs:choice>
<xs:any minOccurs="0" processContents="lax" namespace="##any" />
</xs:sequence>
<xs:attribute name="ID" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
Le code ci-dessus fait fonctionne, tout simplement. Mais il y a quelques mises en garde. La première est xs:any
avec ##other
que son espace de noms. Vous ne pouvez pas utiliser ##any
, à l'exception de la dernière, parce que cela permettrait à des éléments comme l' GivenName
à l'être en place et qui signifie que la définition de l' User
devient ambigu.
Le deuxième inconvénient est que si vous voulez utiliser cette astuce avec plus de deux ou trois, vous aurez à écrire toutes les combinaisons. Un entretien cauchemar. C'est pourquoi je viens avec les éléments suivants:
La solution proposée, une variante d'un Contenu Variable Contenant
Changer votre définition. Cela a l'avantage d'être plus clair à vos lecteurs ou utilisateurs. Il a également l'avantage d'être plus facile à maintenir. Toute une série de solutions sont expliquées sur XFront ici, un moins lisible lien que vous avez déjà vu le post de Oleg. C'est une excellente lecture, mais la plupart ne prennent pas en compte le fait que vous avez un minimum de deux éléments à l'intérieur de la variable contenu du conteneur.
L'actuel meilleur approche pratique pour votre situation (ce qui arrive plus souvent que vous ne l'imaginez) est de séparer vos données entre le nécessaire et non les champs requis. Vous pouvez ajouter un élément <Required>
, ou faire le contraire, l'ajout d'un élément <ExtendedInfo>
(ou de l'appeler Propriétés, ou OptionalData). Ceci se fait comme suit:
<xs:element name="User2">
<xs:complexType>
<xs:sequence>
<xs:element name="GivenName" />
<xs:element name="SurName" />
<xs:element name="ExtendedInfo" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax" namespace="##any" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
Cela peut sembler moins que l'idéal pour le moment, mais de laisser pousser un peu. Avoir un ensemble ordonné d'éléments fixes n'est pas que les grandes d'un accord. Vous n'êtes pas le seul qui va se plaindre de cette carence apparente de W3C XML Schema, mais comme je l'ai dit plus haut, si vous avez à l'utiliser, vous devrez vivre avec ses limites, ou d'accepter le fardeau de développement autour de ces limitations à un coût plus élevé de la propriété.
Solution Alternative
Je suis sûr que vous le savez déjà, mais l'ordre des attributs par défaut est indéterminé. Si votre contenu est de types simples, vous pouvez également choisir de faire une plus grande utilisation des attributs.
Un dernier mot
Quelle que soit l'approche que vous prenez, vous perdez beaucoup de vérifiabilité de vos données. Il est souvent préférable de permettre aux fournisseurs de contenu pour ajouter des types de contenu, mais uniquement lorsqu'il peut être vérifié. Ce que vous pouvez faire en passant d' lax
de strict
traitement et en rendant les types eux-mêmes de plus en plus strictes. Mais être trop strict n'est pas bon, le juste équilibre dépendra de votre capacité à juger les cas d'utilisation que vous êtes contre et pesant que contre le compromis de certaines stratégies de mise en œuvre.