在W3C的XML模式语言(XSD)中是否可以允许一系列元素按任何顺序排列但仍限制出现次数?

时间:2020-03-06 14:27:12  来源:igfitidea点击:

我了解allchoice,但是它们并不能解决我确实希望某些元素能够多次出现的情况,例如:

<Root>
    <ThingA/>
    <ThingB/>
    <ThingC/>
    <ThingC/>
    <ThingC/>
</Root>

我可以使用sequence,但是我更希望允许这些子元素以任何顺序排列。我可以使用any,但是不能超过一个ThingC。我可以使用choice,但是不能将ThingA和ThingB限制为0或者1.

我想我可能在某处已经读到这在XSD中是困难的还是不可能的,但是使用RELAX NG可能是可能的。不幸的是,我不记得我在哪里读的书。

谢谢你的帮助!

解决方案

没错:我们无法在XML Schema中完成我们想做的事情,但是可以在RELAX NG中执行以下操作:

<element name="Root">
  <interleave>
    <element name="ThingA"><empty /></element>
    <element name="ThingB"><empty /></element>
    <oneOrMore><element name="ThingC"><empty /></element></oneOrMore>
  </interleave>
</element>

我们在XML模式中的选项是:

  • 添加一个预处理步骤,该步骤正常化你的输入XML到特定的顺序,然后使用&lt;XS:序列>
  • 使用&lt;xs:choice>,并添加额外的验证(例如,使用Schematron)以检查是否存在不超过一个&lt;ThingA>或者&lt;ThingB>
  • 决定修改标记语言中元素的顺序

事实证明,第三个通常是最佳选择。 XML生成器按特定顺序输出元素通常没有多少成本,而且如果可以提前知道顺序,它不仅有助于验证,而且还有助于XML的使用。