Убедитесь, что содержимое одного элемента равно ключу (ссылка на ключ для содержимого) - PullRequest
0 голосов
/ 05 августа 2020

У меня есть два списка разных элементов (ruleRef и rule) в одном файле XML. Я хотел бы убедиться, что содержимое 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, но они, похоже, ничего не подтвердили.

1 Ответ

1 голос
/ 17 августа 2020

Использование . для xs:field в вашем xs:keyref должно работать, я скорее подозреваю ошибку в XPath для xs:selector.

В элементе <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, и вы можете избавиться от 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>

Это ограничит уникальность имен правил.

...