Il suffit de changer le sélecteur en <xs:selector xpath="answer"/>
et tout ira bien. En général, il est préférable d'éviter les XPaths du type .//*
ne serait-ce que pour des raisons de performance.
Voici le schéma XML pour l'échantillon XML que vous avez fourni et qui, je pense, fonctionne comme vous le souhaitez :
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="question" type="questionType">
<xs:unique name="AnswerIdUnique">
<xs:selector xpath="answer"/>
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>
<xs:complexType name="questionType">
<xs:sequence>
<xs:element name="answer" type="answerType" minOccurs="2" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="answerType">
<xs:sequence>
<xs:element ref="question" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:attribute name="id" type="xs:token" use="required"/>
</xs:complexType>
</xs:schema>
Le XML que vous avez posté se valide correctement avec ce qui précède ; la duplication de l'identifiant d'une réponse sœur entraîne une erreur de validation. Par exemple, le XML suivant :
<question>
<answer id="1">
<question>
<answer id="1"/>
<answer id="2"/>
<answer id="1"/>
</question>
</answer>
<answer id="1">
<question>
<answer id="1"/>
<answer id="2"/>
</question>
</answer>
</question>
Après validation (dans QTAssistant, le message devrait être similaire à celui de Visual Studio puisqu'il est basé sur la même technologie), voici les erreurs :
Error occurred while loading [], line 6 position 5
There is a duplicate key sequence '1' for the 'AnswerIdUnique' key or unique identity constraint.
Error occurred while loading [], line 9 position 3
There is a duplicate key sequence '1' for the 'AnswerIdUnique' key or unique identity constraint.
Document1.xml is invalid.
Vous trouverez ci-dessous une capture d'écran de Visual Studio 2010 montrant la validation XML ci-dessus par rapport au XSD que j'ai posté ; bien que les problèmes soient signalés par inadvertance en tant qu'avertissements, ils sont néanmoins signalés.
J'ai choisi au hasard un validateur en ligne ( http://xsdvalidation.utilities-online.info/ ) et a validé le même XML et XSD que j'ai posté ; l'erreur est signalée comme suit :
org.xml.sax.SAXParseException: Duplicate unique value [1] declared for identity constraint of element "question".org.xml.sax.SAXParseException: Duplicate unique value [1] declared for identity constraint of element "question".
Une chose à laquelle vous devez faire attention est lorsque vous avez un espace de noms cible pour votre XSD ; dans ce cas, il est nécessaire de définir un alias pour tous les espaces de noms impliqués, et de les utiliser dans vos sélecteurs.
MISE À JOUR : Et le XSD avec les espaces de noms :
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://localhost" xmlns="http://localhost" targetNamespace="http://localhost" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="question" type="questionType">
<xs:unique name="AnswerIdUnique">
<xs:selector xpath="tns:answer"/>
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>
<xs:complexType name="questionType">
<xs:sequence>
<xs:element name="answer" type="answerType" minOccurs="2" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="answerType">
<xs:sequence>
<xs:element ref="question" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:attribute name="id" type="xs:token" use="required"/>
</xs:complexType>
</xs:schema>
Veuillez noter l'introduction de la tns
et son utilisation dans le sélecteur.