Схема XML - Можно ли разрешить определенный элемент только один раз во всем документе? - PullRequest
1 голос
/ 05 октября 2011

Я хочу расширить XHTML, чтобы использовать его в качестве языка шаблонов. У меня есть маркерная метка типа

 <mylang:content/>

Я хочу, чтобы этот маркерный тег появлялся там, где могут появляться div или p, но только один раз в полном документе. Я думаю, что это невозможно с XML Schema, но, возможно, некоторые гуру XML Schema знают лучше.

Можно ли разрешить определенный элемент только один раз во всем документе, когда содержащийся элемент может выглядеть неограниченным?

Ответы [ 2 ]

3 голосов
/ 05 октября 2011

Если вы знаете, что корневым элементом будет, то, я думаю, вы можете определить ограничение для элемента doc

<xs:unique name="one-content">
  <xs:selector xpath=".//mylang:content"/>
  <xs:field xpath="."/>
</xs:unique>

Это говорит о том, что все потомки mylang: content должны иметь разные строковые значения; но поскольку элемент ограничен, чтобы быть пустым, если каждый элемент должен быть отличным, то может быть только один элемент.

В XSD 1.1, конечно, с утверждениями становится намного проще.

0 голосов
/ 16 января 2012

Полный пример

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="html">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="body" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="body">
        <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element ref="content" />
            </xs:choice>
        </xs:complexType>
        <xs:unique name="content">
            <xs:selector xpath="content" />
            <xs:field xpath="." />
        </xs:unique>
    </xs:element>

    <xs:element name="content">
        <xs:simpleType>
            <xs:restriction base="xs:string">
                <xs:maxLength value="0" />
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
</xs:schema>

Остерегайтесь: - если вы добавите targetNamespace в свою схему, уникальное ограничение внезапно перестанет работать.Это потому, что xs: unique, xs: key и xs: keyref не используют пространство имен по умолчанию.Вы должны изменить свою схему следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   targetNamespace="http://www.w3.org/1999/xhtml" 
   xmlns="http://www.w3.org/1999/xhtml">

    <xs:element name="html">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="body" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="body">
        <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element ref="content" />
            </xs:choice>
        </xs:complexType>
        <xs:unique name="content" xmlns:html="http://www.w3.org/1999/xhtml">
            <xs:selector xpath="content" />
            <xs:field xpath="." />
        </xs:unique>
    </xs:element>

    <xs:element name="content">
        <xs:simpleType>
            <xs:restriction base="xs:string">
                <xs:maxLength value="0" />
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
</xs:schema>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...