Это невозможно.
Ключ, keyref и unique не помогут.Уникальный гарантирует, что у вас нет дубликатов.И key, и keyref гарантируют, что элементы в месте B совпадают с элементами в месте A.
Ограничение maxOccurs требует простого целочисленного аргумента.Невозможно вычислить целое число любым выражением Xpath.См. Здесь: http://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints
Обновление
Если вы хотите решить свою проблему с уникальным ключом и ключом ref, вам нужно создать числовой индекс в атрибуте.Следующее изображение иллюстрирует схему:
![enter image description here](https://i.stack.imgur.com/Nf7de.png)
Вы должны добавить атрибут к вашим c
узлам, который ссылается на индекс основного атрибута.В этом примере он хранится в нескольких элементах num.Вы можете наложить целочисленное ограничение, ограничение уникальности и ключа на /root/num@count
.После этого вы создаете ссылочное ограничение от /root/a/b/c@count
до /root/num@count
.Это создаст максимальное ограничение.Вы можете иметь столько узлов c
, сколько узлов num
, но их может быть и меньше.
Это схема:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="root">
<xs:annotation>
<xs:documentation>Comment describing your root element</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="num" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="count" type="xs:unsignedInt" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="a" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="b" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="c" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="count" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="num_unique">
<xs:selector xpath="num"/>
<xs:field xpath="@count"/>
</xs:unique>
<xs:key name="num_key">
<xs:selector xpath="num"/>
<xs:field xpath="@count"/>
</xs:key>
<xs:keyref name="num_ref" refer="num_key">
<xs:selector xpath="a/b/c"/>
<xs:field xpath="@count"/>
</xs:keyref>
</xs:element>
</xs:schema>
И это будет действительный файл:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="root.xsd">
<num count="1"/>
<num count="2"/>
<num count="3"/>
<a>
<b>
<c count="1"/>
</b>
<b>
<c count="1"/>
<c count="2"/>
</b>
</a>
</root>
Он станет недействительным, если вы добавите <c count="4"/>
.Прямо сейчас я понятия не имею, как сделать это ссылкой на личность.Возможно, можно изменить референтное направление ...
Но тем не менее не стоит помещать ограничение в тот же файл, что и сами данные. Если вы этого не сделаетедоверяйте своему источнику данных, не имеет смысла просить источник данных для самоопределения ограничений.Вы должны поместить ограничение в схему или расширить валидацию с помощью некоторой логики программы.Например, вы можете подсчитать количество всех c
узлов в их родительском узле и проверить, все ли они одинаковы или равны ли они указанному числу.Это имело бы гораздо больше смысла, потому что это единственный безопасный способ применения ограничения.