确保一个元素的内容等于一个键(内容的keyref)

Ensure that the content of one element is equal to a key (keyref for content)

我在同一个 XML 文件中有两个不同元素的列表(ruleRefrule)。 我想确保 ruleRef 的内容等于任何 rule.

的名称

在我的 XSD 中,我已经有这样的 xs:key 限制:

<xs:key name="ruleName">
  <xs:selector xpath="rules/rule"/>
  <xs:field xpath="@name"/>
</xs:key>

我之前也使用过这个键来验证另一个元素的属性,例如:

<xs:keyref name="differentRuleRef" refer="ruleName">
  <xs:selector xpath="rules/rule/differentRuleRef"/>
  <xs:field xpath="@referencedRule"/>
</xs:keyref>

现在我想验证元素的实际内容而不是属性。 例如。在下面的 XML 中,第二个 <ruleRef> 元素应该是无效的:

<root>
  <rules>
    <rule name="rule1"/>
    <rule name="rule2"/>
  </rules>
  <ruleRefs>
    <ruleRef>rule1</ruleRef>
    <ruleRef>nonExistantRule</ruleRef> <!-- invalid -->
  </ruleRefs>
</root>

我之前尝试过 text()data(.),但是它们在 XPath 子集中都无效。 我也试过 .ruleRef,但他们似乎没有验证任何东西。

使用 . 作为 xs:keyref 中的 xs:field 应该可以,我怀疑 xs:selector.

的 XPath 有误

<root> 元素上,在架构中定义以下内容适用于您提供的 XML 示例:

<xs:element name="root" type="root">
    <xs:key name="ruleName">
        <xs:selector xpath="rules/rule"/>
        <xs:field xpath="@name"/>
    </xs:key>
    <xs:keyref refer="ruleName" name="differentRuleRef">
        <xs:selector xpath="ruleRefs/ruleRef"/>
        <xs:field xpath="."/>
    </xs:keyref>
</xs:element>

<xs:complexType name="root">
   <!-- define root content type here ...-->
</xs:complexType>

另一种方法(稍微简单一些)可能是使用 ID / IDREF 机制,你可以摆脱 shema 中的 xs:key / xs:keyref 定义,并修改规则的定义和 ruleRefs :

   <xs:element name="rule" maxOccurs="unbounded">
      <xs:complexType>
        <xs:attribute name="name" type="xs:ID" />
      </xs:complexType>
   </xs:element>

   <xs:element name="ruleRef" type="xs:IDREF" maxOccurs="unbounded">
   </xs:element>

这将限制规则名称的唯一性。