Я работаю с некоторыми XML-файлами регулярно и хочу иметь лучшую проверку затем, DTD может обеспечить. Таким образом, я начал читать о схемах, чтобы видеть, выручит ли меня. До сих пор я смог создать что-то, что работает почти как, мне нужно за исключением одной части. Я хочу смочь ограничить атрибут элемента к значениям другого атрибута одноуровневого элемента или элементов предка, которые имеют тот же тип элемента. Это даже возможно с XML-схемой key/keyref сжатия?
У меня есть документ, который выглядит примерно так:
<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>
В этом документе узлы могут "расширить" другие узлы, которые являются:
однако, узлы не должны "расширяться":
Это означает, что MyHouse может "расширить" Таблицу, которая не имеет смысла, но я хорошо с этим.
Также важный то, что оба узла дома должны смочь иметь свои собственные узлы под названием DiningRoom.
И моя текущая схема подобна этому:
<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>
Эта схема вносит свой вклад того, что я ищу. Это устанавливает ключи, чтобы быть названиями первого уровня узлов в nodeContainer, и те ключи могут использоваться для "расширения" любого узла на любом уровне в или ниже nodeContainer. И это работает, пока я не хочу "расширять" одноуровневые элементы на более низких уровнях. Документ в качестве примера выше не проверяет из-за этой строки:
<node name="DiningRoom" extends="RoomWithDoor">
В схеме я создал RoomWithDoor, не допустимый ключ для присвоения к, "расширяется", так как это не часть первого уровня узлов в nodeContainer. Но должен там так или иначе записать keys/keyrefs для создания их допустимыми ключами? Размещение keys/keyref определений имеют значение? Действительно ли мои xpaths слишком конкретны (как они могут быть менее конкретными)?