tareas - las asignaciones xml de este libro no son exportables
Cómo crear un esquema xml con key/keyrefs para elementos anidados del mismo tipo (1)
¿Qué pasaría si cambia el selector de XPath para UniqueNodes a
<xs:selector xpath="nodeContainer//node"/>
En otras palabras, cualquier elemento de nodo debajo del nodeContainer. ¿Esto no permitiría lo que quieres lograr?
Trabajo regularmente con algunos archivos XML y quiero tener una mejor validación que una DTD. Entonces comencé a leer sobre esquemas para ver si me ayudaría. Hasta ahora he podido crear algo que funciona casi como lo que necesito, excepto por una sola pieza. Quiero poder restringir el atributo de un elemento a los valores de un atributo diferente de elementos hermanos o antepasados que son del mismo tipo de elemento. ¿Esto es posible incluso con restricciones de key / keyref de XML Schema?
Tengo un documento que se ve así:
<nodeContainer>
<node name="Table">
</node>
<node name="MyHouse">
<node name="RoomWithDoor">
</node>
<node name="DiningRoom" extends="RoomWithDoor">
<node name="DiningTable" extends="Table">
</node>
</node>
</node>
<node name="MySummerHouse">
<node name="DiningRoom">
<node name="DiningTable" extends="Table">
</node>
</node>
</node>
</nodeContainer>
En este documento, los nodos pueden "extender" otros nodos que son:
- hermanos
- hermanos de padres
sin embargo, los nodos no deben "extenderse":
- padres
- Nodos de niños de los hermanos de los padres
Esto significa que MyHouse puede "ampliar" la Tabla , lo cual no tiene sentido, pero estoy de acuerdo con eso.
También es importante que ambos nodos de la casa puedan tener sus propios nodos llamados DiningRoom .
Y mi esquema actual es similar a esto:
<xs:complexType name="node">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="node"/> <!-- node can have other nodes inside it -->
<xs:element ref="leaf"/>
</xs:choice>
<xs:attribute name="name" type="xs:anySimpleType" use="required"/>
<xs:attribute name="extends" type="xs:anySimpleType"/>
</xs:complexType>
<!-- document root -->
<xs:element name="root">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="nodeContainer">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="node"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element ref="otherType"/>
</xs:choice>
</xs:complexType>
<!-- create constrictions -->
<xs:unique name="UniqueNodes">
<xs:selector xpath="nodeContainer/node"/>
<xs:field xpath="@name"/>
</xs:unique>
<xs:keyref refer="UniqueNodes" name="ValidNodeExtends">
<xs:selector xpath=".//node"></xs:selector>
<xs:field xpath="@extends"></xs:field>
</xs:keyref>
</xs:element>
Este esquema hace parte de lo que estoy buscando. Establece las claves para que sean los nombres del primer nivel de nodos en nodeContainer , y esas claves se pueden usar para "extender" cualquier nodo en cualquier nivel en o debajo de nodeContainer . Y eso funciona siempre y cuando no quiera "extender" a los hermanos a niveles más bajos. El documento de ejemplo anterior no se valida debido a esta línea:
<node name="DiningRoom" extends="RoomWithDoor">
En el esquema que he creado, RoomWithDoor no es una clave válida para asignar a "extends", ya que no forma parte del primer nivel de nodos en nodeContainer . Pero, ¿hay alguna forma de escribir las claves / claves para que sean claves válidas? ¿La ubicación de las teclas / definiciones keyref hace la diferencia? ¿Son mis xpaths demasiado específicos (cómo pueden ser menos específicos)?