根据属性值限制元素的出现次数

时间:2015-04-01 11:19:03

标签: xml xsd xsd-validation xsd-1.0

我有一个如下所示的XML:

<Artifacts count="2">
  <Artifact>
    ...
  </Artifact>
  <Artifact>
    ...
  </Artifact>
 </Artifacts>

我正在寻找一种方法来强制使用XSD架构强制Artifact中包含的Artifact元素的数量等于“count”属性的值。

尽管我找到了使用XSD 1.1规范实现这一目标的可能方法,但我想知道如果没有它,它是否完全可能,即基于XSD 1.0规范。


编辑:我会尝试为问题提供更多背景信息,以便更加准确 XML文件将作为C ++应用程序的输入提供。问题是开发环境强制使用Xerces v.2.8.0库进行解析。据我了解,此版本不支持XSD 1.1标准。

当然,我可以添加额外的代码,以便在XSD验证后检查Artifact个元素的正确出现次数。我希望有一种方法可以避免额外的代码段,并完全验证基于XSD的输入文件。

2 个答案:

答案 0 :(得分:2)

您想要建模的约束类型的正确术语是断言。不,XML Schema 1.0中无法断言。唯一支持断言的验证语言是XML Schema 1.1(xs:assert)和Schematron(sch:assertsch:report)。

除此之外,您可以编写XPath表达式或XSLT样式表来测试正确数量的Artifact元素:

/Artifacts/@count = count(/Artifacts/Artifact)

  

XML文件将作为C ++应用程序的输入提供。问题是开发环境强制使用Xerces v.2.8.0库进行解析。据我了解,此版本不支持XSD 1.1标准。

我的猜测是Xerces 2.8.0(不再支持的过时版本)不符合XSD 1.1,但最简单的方法是简单地测试它。在模式中包含任何xs:assert,看看会发生什么。

  

当然,我可以添加额外的代码,以便在XSD验证后检查“Artifact”元素的正确出现次数。我希望有一种方法可以避免额外的代码段,并完全验证基于XSD的输入文件。

不,只有XSD 1.0,你无法避免这些额外的代码行。


编辑 @kjhughes在评论中写的内容实际上应该是答案的一部分:

  

这是正确的,我也会挑战OP的设计,该设计需要一个仅反映子属性数量的属性。

从XML设计的角度来看,如果此属性除了声明有多少Artifact个元素之外什么也没做,那么为什么首先要包含它?您应始终不愿意存储冗余和可恢复的信息。例如,不需要存储子元素的位置,如下所示:

<root>
  <child n="1"/>
  <child n="2"/>
</root>

您的count属性非常相似。

答案 1 :(得分:1)

我假设计数值是动态的,基于Artifact元素的实际数量。一种方式(因为我不知道你的上下文是什么)可以用minOccurs修改XSD,并根据这个值修改maxOccurs,然后根据新模式进行验证...

<xsd:complexType name="Artifacts">
    <xsd:sequence>
      <xsd:element name="Artifact" minOccurs="COUNT_VALUE" maxOccurs="COUNT_VALUE" />      
    </xsd:sequence>   
</xsd:complexType>