The ELEMENT Type Declaration can be used within an DTD to define the contents on an element within the XML document.
An element can contain a number of child elements, the choice, sequence and cardinality constructs control which child elements are allowed, how many and in what order. By nesting choices and sequences complex rules can be created.
The number of times a child XML Element appears within the XML Document can be controlled using the cardinality operators.
Operator | Cardinality | Description |
---|---|---|
1-1 | By default a child element is required (it must appear once within the XML document). | |
? | 0-1 | Optional operator, the element does not have to appear within the XML Document |
* | 0-n | Zero to Many operator, the element can appear 0 or more times |
+ | 1-n | One to Many operator, the element can appear 1 or more times. |
DTD | Sample XML |
---|---|
<!ELEMENT test (a)> |
<test><a/></test> |
<!ELEMENT test (a?)> or <!ELEMENT test (a)?> |
<test></test> or <test><a/></test> |
<!ELEMENT test (a,b+)> |
<test><a/><b/><b/></test> |
If the sequence operator ',' is used, then the encloses constructs must appear in the order they are defined.
The sequence may contain nested sequences or choices.
The sequence construct may also have a cardinality operator, indicating how many times the entire sequence may occur.
DTD | Sample XML |
---|---|
<!ELEMENT test (a)> |
<test><a/></test> |
<!ELEMENT test (a?, b, c+, d*)> |
<test><b/><c/></test> or <test><a/><b/><c/><c/><d/><d/></test> |
<!ELEMENT test (a?, b, (c?, d)*)> |
<test><a/><b/><d/></c></d></d></test>
|
If the choice operator is used, then only 1 of the enclosed constructs can appear.
The choice must contain at least 2 names, nested sequences or nested choices.
The choice construct may also have a cardinality operator, indicating how many times the entire choice construct may occur.
DTD | Sample XML |
---|---|
<!ELEMENT test (a | b)> |
<test><a/></test> or <test><b/></test> |
<!ELEMENT test (a? | b | c+ | d*)> |
<test><a/></test> or <test><b/></test> or <test><c/></test> or <test><d/><d/></test> or <test></test> |
<!ELEMENT test (a? | b | (c?, d)*)> |
<test><a/></test> or <test><b/></test> or <test><d/></c></d></d></test>
|
Defines an element that has not content, i.e. no character data or child nodes.
It may still contain attributes.
DTD | Sample XML |
---|---|
<!ELEMENT test EMPTY> |
<test></test> or <test/> |
<!ELEMENT test EMPTY> <!ATTLIST test name CDATA #REQUIRED> |
<test name="fred"></test> or <test name="fred/> |
Defines an XML Element that can contain any content, CDATA, Comments, Processing Instructions, or child elements that have been declared elsewhere in the DTD. It does not make any assertions about the attributes that the element may contain.
DTD | Sample XML | ||||||||
---|---|---|---|---|---|---|---|---|---|
<!ELEMENT test ANY> |
<test></test> or <test/> |
||||||||
<!ELEMENT test ANY> <!ELEMENT myElm EMPTY> |
|
Allows character data to appear interspersed with child elements. The syntax for this rule is quite specific. The #PCDATA has to be the first item in the first choice, and the choice has to have 0-n occurrences.
DTD | Sample XML | ||||
---|---|---|---|---|---|
<!ELEMENT name (#PCDATA)* > |
<test>Some Text</test> Only character data is allowed |
||||
<!ELEMENT name (#PCDATA | br | strong)* > |
<test>Some <strong>important</strong> Text</br></test> |
||||
|
Invalid. If #PCDATA is used it must be within a choice (not a sequence). | ||||
|
Invalid. If #PCDATA is used it must be the first item in the opening choice. | ||||
|
Invalid. If #PCDATA is used then the sequence must be 0-1 (it must have a '*' on the end) |
You can not mix sequence and choice identifiers in the same construct, if you want to mix them they have to be enclosed in brackets
Valid DTD |
Copy Code
|
---|---|
<!ELEMENT test (a, b, c, (d | e))> <!ELEMENT test (a, b, ( c | (d, e)))> |
Invalid DTD |
Copy Code
|
---|---|
<!ELEMENT test (a, b, c, d | e)> <!ELEMENT test (a, b, ( c | d, e))> |
The following EBNF describes the form the declaration takes.
[45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
[46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
[47] children ::= (choice | seq) ('?' | '*' | '+')?
[48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
[49] choice ::= '(' S? cp ( S? '|' S? cp )+ S? ')'
[50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
[51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'
| '(' S? '#PCDATA' S? ')'
The above EBNF is a little confusing as the whitespace and braces make it difficult to read, simplified it looks like this, the blue characters are literals, the black is EBNF syntax.
[45] elementdecl ::= <!ELEMENT name EMPTY> |
<!ELEMENT name ANY> |
<!ELEMENT name (#PCDATA)> |
<!ELEMENT name (#PCDATA (| name)* )*> |
<!ELEMENT name name (? | * | +)?> |
<!ELEMENT name choice (? | * | +)?> |
<!ELEMENT name seq (? | * | +)?>
[48] cp ::= (name | choice | seq) (? | * | +)?
[49] choice ::= ( cp (| cp )+ )
[50] seq ::= ( cp (, cp )* )