У меня есть 2 основных раздела в файле XML Sequence и StateRelations. Секция Последовательность определяется как. Элемент Transition должен быть unqiue на основе его 4 свойств, как определено ниже.XSD 1.1 Проверьте, существует ли атрибут в другом элементе
<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 может повторяться в Transitions. Теперь у нас есть конфликт. Моя конечная цель будет иметь
уникальных последовательностей на основе 4 атрибутов
и каждый stateName1 в StateRelations должен быть действительным StateName определены в переходах.
До сих пор, я знаю, что ключ-KeyRef не будет работать в моем сценарии, так что я начал смотреть в утверждают, но я не могу заставить его работать. Я пробовал следующее, но ничего не работает.
<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>
EDIT: Вот 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>
Да, мой элемент верхнего уровня - Replay. Вы совершенно правы. Благодарю. Однажды я переместил свое утверждение на уровень Replay, и он работал нормально. Единственная проблема заключается в том, что я не могу использовать key/keyref, потому что stateName в переходах не уникален. Итак, поскольку утверждение является моим единственным вариантом, и я должен определить его вне тега Relation, я использую какой-то цикл for в XPath, чтобы проверить, существуют ли в Transition имена состояний, определенные в Relation? –
Извините, я не думаю, что понимаю вашу структуру достаточно хорошо, чтобы понять, почему использование ключа/keyRef является проблемой. Когда вы говорите о циклах в XPath, это для key/keyRef или для утверждений? XPath, конечно, не имеет циклов, он полностью декларативный и работает над наборами узлов. –
Простите за то, что не ясны. Я обновил свой вопрос. –