XML, DTD: how to make the order not important

倖福魔咒の 提交于 2019-11-27 22:52:34

As Roger said, there are only ordered lists, but you can use operator OR | to define all accepted combinations

<!ELEMENT level ((file,filelName?,fileNumber?)|(filelName?,fileNumber?,file))>

Look here, there is an example in the section Choices

Declaring unordered lists with occurrence constraints in DTD will often result in long or complicated looking declarations. One big reason for this is that DTDs must be deterministic, therefore even switching to XML Schemas don't necessarily help.

Here is a DTD declaration for element <level> that contains:

  • exactly 1 <file> element
  • 0-1 <fileName> elements
  • 0-1 <fileNumber> elements
  • in any possible order

code:

<!ELEMENT level ( (file, ((fileName, fileNumber?) | (fileNumber, fileName?))?)
                 |(fileName, ((file, fileNumber?) | (fileNumber, file)))
                 |(fileNumber, ((file, fileName?) | (fileName, file))) )>

You can use ANY keyword if you don't bother too much about validity:

<!ELEMENT level ANY>

I have faced a similar problem here, this two cases may appear:

<Instructors>
  <Lecturer>
  </Lecturer>
  <Professor>
  </Professor>
</Instructors>

<Instructors>
  <Lecturer>
  </Lecturer>
  <Professor>
  </Professor>
</Instructors>

The only solution I found was this:

<!ELEMENT Instructors ANY>

Maybe there are a better solution, but it works fine for my particular problem.

With a DTD the child nodes have to appear in the order listed in the element definition. There is no way to allow for alternative orderings, unless you want to upgrade to an XSD schema.

Addendum: Per @Gaim, you can offer alternative orders using the (a,b,c...)|(b,a,c...) syntax, but this is not really practical for more than, say, 3 nested elements, since an arbitrary order allows for a factorial number of orderings -- 6 for 3 elements, 24 for 4 elements, 120 for 5 elements -- and clever use of ? operators is sure to result in false validation for strange cases.

If you can guess sensible upper-bound for the number of children for your element, than there is extremely dirty way how to overcome the problem. Follows the example for 0-3 children:

<!ELEMENT myUnorderedElement ( (option1 | option2 | option3)?, (option1 | option2 | option3)?, (option1 | option2 | option3)? >

Thus, you allow the element "myUnorderedElement" to have 0-3 children of any of type option1, option2 or option3.

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