У меня есть 2 основных раздела в моем XML-файле Sequence и StateRelations. Раздел Sequence определяется как. Элемент Transition должен быть уникальным на основании его 4 свойств, как определено ниже.
<xs:element name="Transition">
<xs:complexType>
<xs:sequence>
<xs:element ref="Element1" minOccurs="0" maxOccurs="1"/>
<xs:element ref="Element2" minOccurs="0" maxOccurs="1"/>
<xs:element ref="Element3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="stateName" type="xs:string" use="required"/>
<xs:attribute name="A" type="xs:string" use="required"/>
<xs:attribute name="B" type="xs:string" use="required"/>
<xs:attribute name="C" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="Sequence">
<xs:complexType>
<xs:sequence>
<xs:element ref="Transition" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute ref="xml:base"/>
</xs:complexType>
<xs:unique name="uniqueTransition">
<xs:selector xpath=".//Transition"/>
<xs:field xpath="@stateName"/>
<xs:field xpath="@A"/>
<xs:field xpath="@B"/>
<xs:field xpath="@C"/>
</xs:unique>
</xs:element>
и раздел StateRelations определяется следующим образом. «stateName1» на самом деле является внешним ключом (keyref), который связан с «stateName» (ключом) перехода. Примечание. Элемент отношения фактически рекурсивен.
<xs:element name="Relation">
<xs:complexType>
<xs:sequence>
<xs:element ref="Relation" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="stateName1" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="StateRelations">
<xs:complexType>
<xs:sequence>
<xs:element ref="Relation" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute ref="xml:base"/>
</xs:complexType>
</xs:element>
Проблема возникает в следующем сценарии. Поскольку Transition имеет уникальное ограничение, основанное на 4 атрибутах, следующий XML действителен.
<Transition stateName="S3" A="a1" B="b1" C="c"/>
<Transition stateName="S3" A="a" B="b" C="c"/>
Как видите, stateName = S3 может повторяться несколько раз. Но это повторение нарушает отношения первичного и внешнего ключа между переходом и отношениями. Причина: stateName может повторяться в переходах. Теперь у нас здесь конфликт. Моей конечной целью было бы иметь
Уникальные последовательности на основе 4 атрибутов
и каждое stateName1 в StateRelations должно быть действительным stateName, определенным в Transitions.
До сих пор я знаю, что key-keyref не будет работать в моем сценарии, поэтому я начал изучать assert, но не могу заставить его работать. Я пробовал следующее, но, похоже, ничего не работает.
<xs:element name="Relation">
<xs:complexType>
<xs:sequence>
<xs:element ref="Relation" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="stateName1" type="xs:string" use="required"/>
<xs:assert test="matches( .//Transition/@stateName , @stateName1 )"/>
<xs:assert test="/Replay/Sequence/Transition[contains(@stateName, @stateName1)]" />
<xs:assert test="/Replay/Sequence/Transition[contains(@stateName, string( @stateName1 ))]/@stateName = string(@stateName1) "/>
</xs:complexType>
</xs:element>
РЕДАКТИРОВАТЬ: вот XSD (я опустил некоторые детали). Теперь я хочу как-то проверить, что /Replay/StateRelations/Relation/@stateName1
существует в /Replay/Sequence/Transition/@stateName
. Я не могу использовать key / keyref, потому что /Replay/Sequence/Transition/@stateName
не будет уникальным.
<Replay>
<xs:element name="Relation">
<xs:complexType>
<xs:sequence>
<xs:element ref="Relation" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="stateName1" type="xs:string" use="required"/>
<xs:assert test="matches( .//Transition/@stateName , @stateName1 )"/>
<xs:assert test="/Replay/Sequence/Transition[contains(@stateName, @stateName1)]" />
<xs:assert test="/Replay/Sequence/Transition[contains(@stateName, string( @stateName1 ))]/@stateName = string(@stateName1) "/>
</xs:complexType>
</xs:element>
<xs:element name="StateRelations">
<xs:complexType>
<xs:sequence>
<xs:element ref="Relation" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute ref="xml:base"/>
</xs:complexType>
</xs:element>
<xs:element name="Transition">
<xs:complexType>
<xs:sequence>
<xs:element ref="Element1" minOccurs="0" maxOccurs="1"/>
<xs:element ref="Element2" minOccurs="0" maxOccurs="1"/>
<xs:element ref="Element3" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="stateName" type="xs:string" use="required"/>
<xs:attribute name="A" type="xs:string" use="required"/>
<xs:attribute name="B" type="xs:string" use="required"/>
<xs:attribute name="C" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="Sequence">
<xs:complexType>
<xs:sequence>
<xs:element ref="Transition" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute ref="xml:base"/>
</xs:complexType>
<xs:unique name="uniqueTransition">
<xs:selector xpath=".//Transition"/>
<xs:field xpath="@stateName"/>
<xs:field xpath="@A"/>
<xs:field xpath="@B"/>
<xs:field xpath="@C"/>
</xs:unique>
</xs:element>
</Replay>