2012-04-27 28 views
10

tengo un documento XML estructurado como Q & A, que sigue el siguiente formato (editado para mayor claridad):XSD restricción única en atributo de elementos relacionados de un tipo específico

<question> 
    <answer id="1"> 
     <question> 
      <answer id="1"/> 
      <answer id="2"/> 
      <answer id="3"/> 
     </question> 
    </answer> 
    <answer id="2"> 
     <question> 
      <answer id="1"/> 
      <answer id="2"/> 
     </question> 
    </answer> 
</question> 

Mi XSD se ve así:

<xs:element name="question"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element name="answer" type="answerType" minOccurs="2" maxOccurs="unbounded"> 
      </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
    <xs:unique name="AnswerIdUnique"> 
     <xs:selector xpath="./*" /> 
     <xs:field xpath="@id" /> 
    </xs:unique> 
</xs:element> 

<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> 

Por supuesto, hay algo más que lo que ves arriba, pero esto ilustra mi problema. Necesito que el atributo id en answer sea único entre los hermanos. El XSD definido anteriormente impone la unicidad de los atributos id entre los elementos hermanos, pero no discrimina en el tipo de elemento. He intentado una variedad de selectores y campos en la restricción única, pero no he encontrado una combinación que funcione. ¿Alguna sugerencia?

Respuesta

14

Simplemente cambie el selector a <xs:selector xpath="answer"/> y todo irá bien. En general, es bueno evitar XPath como .//*, solo por motivos de rendimiento.

Este es el esquema XML para el XML de ejemplo que nos ha facilitado que creo que está funcionando de la manera deseada:

<?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> 

Su XML Posteado valida bien con lo anterior; duplicar la id de cualquier respuesta de hermano produce un error de validación. Por ejemplo, el siguiente código XML:

<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> 

Cuando validado (en QTAssistant, debe ser similar al mensaje en Visual Studio ya que se basa en la misma tecnología), estos son los errores:

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. 

A continuación se muestra una captura de pantalla de Visual Studio 2010 que muestra la validación XML anterior frente al XSD que publiqué; aunque los problemas se informan inadvertidamente como advertencias, no obstante, se informan.

VS2010 showing unique constraint errors

he elegido al azar un validador en línea (http://xsdvalidation.utilities-online.info/) y validado el mismo XML y XSD que he publicado; el error se reporta como:

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".

Una cosa que hay que prestar atención es cuando se tiene un espacio de nombres para su XSD; en ese caso, es necesario definir un alias para todos los espacios de nombres implicados y usarlos en sus selectores.

ACTUALIZACIÓN: Y el XSD con espacios de nombres:

<?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> 

por favor que la introducción del tns prefijo y el uso del mismo en el selector.

+0

esto no parece funcionar por alguna razón. Por favor vea mi pregunta actualizada – joelmdev

+0

Si supiera por qué no funcionó, no publicaría la pregunta en primer lugar, por lo tanto, la declaración por alguna razón no funciona. Estoy usando VS2010 y parece que todas las variantes que contienen "respuesta" en el selector xpath se niegan a funcionar. La eliminación de la constancia única de answerType y la adición de ref = "pregunta" provocaron un error vago que simplemente decía "El atributo 'ref' no puede estar presente."La edición es lo más cerca que he llegado al código de trabajo. Publique su xsd y lo intentaré localmente. Gracias por acompañarme, han pasado años desde que tuve que escribir un documento de esquema XML y estoy oxidado. – joelmdev

+0

Petru, ¿qué software está utilizando para trabajar con XML y validarlo con el esquema? – joelmdev

Cuestiones relacionadas