#xml #xsd
#xml #xsd
Вопрос:
вот мой XML-документ
<root>
<num>3</num>
<a>
<b>
<c n="m"></c>
<c></c>
<c n="e"></c>
</b>
<b>
<c n="s"></c>
<c n="w"></c>
<c></c>
</b>
<b>
<c n="q"></c>
<c></c>
<c n="u"></c>
</b>
</a>
</root>
Я хочу создать XML-схему.
Элемент c в b должен встречаться только n раз.(n находится в элементе num)
Я думаю, что он использует key, keyref или unique.
Ответ №1:
Это невозможно.
Key, keyref и unique не помогут. Уникальность гарантирует, что у вас нет повторяющихся элементов. А key и keyref гарантируют, что элементы на месте B соответствуют элементам на месте A.
Ограничение maxOccurs требует простого целочисленного аргумента. Невозможно вычислить целое число с помощью какого-либо выражения Xpath. Смотрите здесь: http://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints
Обновить
Если вы хотите решить свою проблему с помощью unique, key и key ref, вы должны создать числовой индекс в атрибуте. Следующее изображение иллюстрирует схему:
Вы должны добавить атрибут к своим 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
узлов в их родительском элементе и проверить, все ли они одинаковы или все равны заданному числу. Это имело бы гораздо больше смысла, потому что это единственный безопасный способ принудительно ввести ограничение.
Комментарии:
1. таким образом, единственный способ — maxOccurs =»неограниченный»