Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DTD when element order does not matter

Tags:

xml

dtd

I can't figure out how to write DTD for XML file which can contain same elements in mixed order.

Small example which shows the problem is below:

<root>

  <element>
    <one></one>
    <two></two>
  </element>

  <element>
    <two></two>
    <one></one>
  </element>

  <element>
    <two></two>
    <two></two>
    <two></two>
    <two></two>
    <one></one>
    <one></one>
  </element>

</root>

My DTD:

<!ELEMENT root(element*)>
<!ELEMENT element((one*,two*)|(two*,one*))>

I found a similar topic but the solution does not work in my case (and I'm not sure what is wrong with my DTD at the moment). I get this error message:

xmllint: Content model of Instructors is not determinist: ((one* , two*) | (two* , one*))
like image 329
afaf12 Avatar asked May 01 '26 09:05

afaf12


2 Answers

<!ELEMENT element (one|two)*>

(Or + if you must have at least one.)

like image 115
Dave Newton Avatar answered May 02 '26 22:05

Dave Newton


Your solution is not deterministic, because

<element>
    <two/>
</element>

is one of the cases that matches both of the branches: (one*, two*) and (two*, one*).

Like @Cristopher noted, @Dave's answer allows mixed ordering and his answer fixes that problem. But actually Christopher's answer is not deterministic either, because when validating input

<element>
    <two/>
</element>

and the validator encounters the first <two> it doesn't know which branch it should select. It only knows this after all of the <two> elements are read.

To keep the order consistent while keeping the model deterministic, use

<!ELEMENT element ( (one+, two*) | (two+, one*) )? >

Key points here are: 1) keeping the model deterministic by beginning each branch with a different mandatory element 2) but still allowing empty <element/> with the ? in the end which makes the content model optional.

like image 44
jasso Avatar answered May 02 '26 23:05

jasso



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!