问题
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