Validating XML against DTD in which elements appears in random order
<!ELEMENT myxml (first,second,third)>
<!ELEMENT first (#PCDATA)>
<!EL开发者_如何转开发EMENT second (#PCDATA)>
<!ELEMENT third (#PCDATA)>
The DTD above restricts the child element (first, second and third) to be in the same order in the XML. Is there any way that this DTD can validate to the XML in which the elements are compulsory but can appear in any order?
This is tricky when you need exactly one of each child elements. This is the only way I can think of and it's not very pretty. It works though...
<!ELEMENT myxml (
(first,second,third)|
(first,third,second)|
(second,first,third)|
(second,third,first)|
(third,first,second)|
(third,second,first)
)>
<!ELEMENT first (#PCDATA)>
<!ELEMENT second (#PCDATA)>
<!ELEMENT third (#PCDATA)>
Basically I'm specifying every possible combination of exactly one first
, second
, and third
elements.
Here's an example instance. first
, second
, and third
can be in any order, but they each must occur exactly one time.
<!DOCTYPE myxml [
<!ELEMENT myxml (
(first,second,third)|
(first,third,second)|
(second,first,third)|
(second,third,first)|
(third,first,second)|
(third,second,first)
)>
<!ELEMENT first (#PCDATA)>
<!ELEMENT second (#PCDATA)>
<!ELEMENT third (#PCDATA)>
]>
<myxml>
<third></third>
<first></first>
<second></second>
</myxml>
<!ELEMENT myxml (first|second|third)*>
<!ELEMENT first (#PCDATA)>
<!ELEMENT second (#PCDATA)>
<!ELEMENT third (#PCDATA)>
The above isn't very useful, though. You'd be more likely to want to require at least one child, like this:
<!ELEMENT myxml (first|second|third)+>
<!ELEMENT first (#PCDATA)>
<!ELEMENT second (#PCDATA)>
<!ELEMENT third (#PCDATA)>
In XML DTDs, there is no elegant way to specify this constraint. You can do as @DevNull suggests; it is legal, but the technique becomes unwieldy when the number of elements is large.
If this had been about an SGML DTD, then you could have used the &
(AND) connector. But that is one of the features that was removed when XML was created.
精彩评论