Xml XSD 1.1检查另一个元素中是否存在属性

Xml XSD 1.1检查另一个元素中是否存在属性,xml,xpath,xsd,xsd-validation,xsd-1.1,Xml,Xpath,Xsd,Xsd Validation,Xsd 1.1,在XML文件序列和状态关系中有两个主要部分。序列段定义为。根据下面定义的4个属性,Transition元素应该是unqiue <xs:element name="Transition"> <xs:complexType> <xs:sequence> <xs:element ref="Element1" minOccurs="0" maxOccurs="1"/> <xs:e

在XML文件序列和状态关系中有两个主要部分。序列段定义为。根据下面定义的4个属性,Transition元素应该是unqiue

<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/Sequence/Transition
,可能还有另一个单独的分支
/Replay/StateRelations/Relations

如果是这种情况,那么定义
Transition
Relation
之间关系的约束需要在公共祖先的级别上定义,即
Replay
。您可以在此级别上使用key/keyref或使用断言来定义它,但无论哪种方式,影响两个不同元素的约束始终需要在公共祖先级别上定义:因为在此祖先上扎根的树是文档中最小的自包含部分,因此无效


更具体地说,请注意断言不能查看定义断言的元素所在子树之外的数据。它是关于该元素及其内容的断言,而不是关于该元素周围上下文的断言。

是的,我的顶级元素是Replay。你完全正确。谢谢有一次,我将我的断言移动到了重播级别,它工作得很好。唯一的问题是我不能使用key/keyref,因为转换中的stateName不是唯一的。因此,由于断言是我唯一的选择,我必须在关系标记之外定义它,我是否必须在XPath中使用某种for循环来检查在关系中定义的状态名是否存在于转换中?对不起,我认为我对您的结构了解不够,无法理解为什么使用key/keyRef是一个问题。当您谈到XPath中的循环时,这是用于key/keyRef还是用于断言?XPath当然没有循环,它是完全声明性的,可以在节点集上工作。很抱歉,不清楚。我已经更新了我的问题。
<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 stateName="S3" A="a1" B="b1" C="c"/>
<Transition stateName="S3" A="a" B="b" C="c"/>
    <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>
<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>