validación xsd basada en dos claves
Frecuentes
Visto 406 equipos
1
Quiero validar el siguiente xml:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<root1>
<items>
<item id="1">
<interfaces>
<interface id="0"/>
<interface id="1"/>
<interface id="2"/>
</interfaces>
</item>
<item id="2">
<interfaces>
<interface id="10"/>
<interface id="11"/>
<interface id="2"/>
</interfaces>
</item>
</items>
<connections>
<connection id="1">
<point item="1" interface="0"/>
<point item="2" interface="10"/>
</connection>
<connection id="2">
<point item="1" interface="1"/>
<point item="2" interface="11"/>
</connection>
<connection id="3">
<point item="1" interface="2"/>
<point item="2" interface="157"/> <-- this one is not valid as there is no interface 157 under item 2.
</connection>
</connections>
</root1>
</root>
Ese es el código para validar el artículo:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="root1" type="root1" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:keyref name="endPointIntfKeyRef" refer="interfaceKey">
<xs:selector xpath="root1/connections/connection/point"/>
<xs:field xpath="@interface"/>
</xs:keyref>
</xs:element>
<xs:complexType name="root1">
<xs:sequence>
<xs:element name="items" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="item" type="item" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="connections" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="connection" type="connection" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="item">
<xs:sequence>
<xs:element name="interfaces" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="interface" type="interface" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="interfaceKey">
<xs:selector xpath="interface"/>
<xs:field xpath="@id"/>
</xs:unique>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="interface">
<xs:attribute name="id" type="xs:int" use="required"/>
</xs:complexType>
<xs:complexType name="connection">
<xs:sequence>
<xs:element name="point" minOccurs="2" maxOccurs="2">
<xs:complexType>
<xs:attribute name="item" type="xs:int" use="required"/>
<xs:attribute name="interface" type="xs:int" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:int" use="required"/>
</xs:complexType>
</xs:schema>
Pero produce 'Se encontró más de una coincidencia para la secuencia de teclas' que no quiero tener ya que las interfaces son únicas en un elemento específico.
$ xmllint --noout --schema 1.xsd 1.xml
1.xml:31: Schemas validity error : Element 'point': More than one match found for key-sequence ['2'] of keyref 'endPointIntfKeyRef'.
1.xml:32: Schemas validity error : Element 'point': No match found for key-sequence ['157'] of keyref 'endPointIntfKeyRef'.
1.xml fails to validate
¿Cómo obtener solo el segundo error 'Elemento 'punto': no se encontró ninguna coincidencia para la secuencia de teclas ['157'] de keyref 'endPointIntfKeyRef' y no la primera?
1 Respuestas
1
El mensaje de error es correcto - hay están dos posibles coincidencias en el interfaceKey
para el valor keyref 2
. Para obtener el comportamiento que necesita, necesitaría un valor de clave compuesto que incluya el item
identificación, así como el interface
ID que luego podría keyref
usando tanto el item
y interface
atributos en point
, pero eso significaría definir el unique
restricción como
<xs:unique name="interfaceKey">
<xs:selector xpath="interface"/>
<xs:field xpath="../@id"/><!-- not allowed in 1.0 -->
<xs:field xpath="@id"/>
</xs:unique>
y XML Schema 1.0 no permite ..
en expresiones XPath de campo o selector (restringidas).
Respondido 15 Feb 14, 20:02
Gracias, ¿en qué versión de esquema xml es compatible? ¿Y cómo cambiar mi código para usarlo? - vitalivanov
@vitalivanov XML Schema v1.1 permite el lenguaje XPath 2.0 completo, pero no es tan ampliamente compatible como 1.0. Una alternativa podría ser investigar el uso de reglas de Schematron para expresar las restricciones que no puede hacer en el esquema básico. - Ian Roberts
Entonces, ¿este tipo de validación no es posible en el esquema 1.0? - vitalivanov
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas xml xsd xmllint or haz tu propia pregunta.
Este material de referencia clave era nuevo para mí. Encontré que la siguiente página es una buena explicación: zvon.org/xxl/XMLSchemaTutorial/Output/ser_keys_st5.html - Mark O'Connor