Это можно решить несколькими способами, некоторые лучше, чем другие
решение с использованием Assert - но не большой один ...
В XSD 1.1 вы можете сделайте это, используя <xs:assert>
. В идеале утверждение будет помещено на ссылочный элемент <Restriction>
, это затем сделает очевидным, что <Restriction>
недействителен.
Однако, поскольку <xs:assert>
не может получить доступ к значениям выше в дереве <xs:assert>
должен быть достаточно высоко, чтобы иметь <Restriction>
и <Variable>
в своем объеме (дети). Это было бы хорошо, но теперь вам нужно написать общее правило, которое, если оно терпит неудачу, не даст большой обратной связи - оно просто скажет вам, что один или несколько из <Restriction>
недействительны.
Heres очень быстрый образец для демонстрации.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.0 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="base">
<xs:complexType>
<xs:sequence>
<xs:element name="var" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="Usage" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:assert test="count(Usage[not(./text() = ../var/text())]) = 0" />
</xs:complexType>
</xs:element>
</xs:schema>
Пример XML-
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid XML 2016 Developer Bundle Edition 14.1.4.6649 (https://www.liquid-technologies.com) -->
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Schema.xsd">
<var>var1</var>
<var>var2</var>
<var>var4</var>
<Usage>var1</Usage>
<Usage>var2</Usage>
<Usage>var3</Usage><!-- INVALID -->
</base>
Сообщение об ошибке (через Saxon)
(10: 7) Критический CVC-утверждение: оценка Утверждение ('Count (Использование [not (./ text() = ../ var/text())]) = 0 ') для элемента' base 'в типе схемы' #AnonType_base 'не удалось.
Лучшее решение с использованием ключа/KeyRef-х
Это XSD 1,0 дружественных и работает довольно хорошо. Он сообщает вам, есть ли у вас дубликаты имен переменных, а также, если ссылка на имя переменной неверна, указывая на фактическую проблему.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.0 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="base">
<xs:complexType>
<xs:sequence>
<xs:element name="Variables">
<xs:complexType>
<xs:sequence>
<xs:element name="Variable" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Restrictions">
<xs:complexType>
<xs:sequence>
<xs:element name="Restriction" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="variable" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="VarDef">
<xs:selector xpath="./Variables/Variable" />
<xs:field xpath="@name" />
</xs:key>
<xs:keyref name="VarRef" refer="VarDef">
<xs:selector xpath="./Restrictions/Restriction" />
<xs:field xpath="@variable" />
</xs:keyref>
</xs:element>
</xs:schema>
Пример XML
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.0 (https://www.liquid-technologies.com) -->
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SchemaKeyRef.xsd">
<Variables>
<Variable name="var1"></Variable>
<Variable name="var2"></Variable>
<Variable name="var3"></Variable>
</Variables>
<Restrictions>
<Restriction variable="var1">string</Restriction>
<Restriction variable="var2">string</Restriction>
<Restriction variable="UNKNOWN">string</Restriction>
</Restrictions>
</base>
Теперь ошибка генерируется гораздо конкретнее, что делает отладку проблемы гораздо проще.
Ошибка От .Net (Номер строки является плохим Restriction)
(12:10) Ошибка последовательности клавиша 'UNKNOWN' в '' VarDef KeyRef не может ссылаться на какой-то ключ.
Ошибка из Saxon (Номер строки является содержащий элемент базы)
(14: 7) Критический CVC-идентичности constraint.4.3: Key 'VarRef' со значением 'НЕИЗВЕСТНЫЙ' не найден идентичности ограничение элемента «база».