XML Schema - Is it possible to allow a certain element only once in the whole document?

爱⌒轻易说出口 提交于 2019-12-23 02:17:14

问题


I want to extend XHTML to use it as a template language. I have a marker tag like

 <mylang:content/>

I want this marker tag to appear where div or p can appear, but only once in the complete document. I think it is not possible with XML Schema, but maybe some XML Schema guru knows better.

Is it possible to allow a certain element only once in the whole document when the containing element is allowed to appear unbounded?


回答1:


If you know that the root element will be , then I think you can define a constraint on the doc element

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

This says that all mylang:content descendants must have distinct string values; but since the element is constrained to be empty, if every element must be distinct then there can only be one element.

In XSD 1.1 of course it becomes much easier with assertions.




回答2:


Full Example

<?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>

Beware of: - if you add a targetNamespace in your schema, the unique constraint suddenly stops working. This is because xs:unique, xs:key and xs:keyref dont use default namespace. you have to change your schema like this:

<?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>


来源:https://stackoverflow.com/questions/7661652/xml-schema-is-it-possible-to-allow-a-certain-element-only-once-in-the-whole-do

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!