我有一个XML& XSD耦合包括类似于以下内容的'House'元素:
<root>
...
<House>
<id>1</id>
<type>Cottage</type>
<imageSrc> image.jpg </imageSrc>
</House>
<House>
<id>2</id>
<type>Private</type>
</House>
我想通过我的XSD强制执行所有类型为“Cottage”的房屋必须有强制标签,但其他房屋则没有。 (或者另一种方式aruond - 唯一的'私有'做不。有没有办法做到这一点?
答案 0 :(得分:2)
您可能需要考虑使用类似Schematron之类的内容来表达超出XML Schema功能的其他验证规则。 Schematron是一个开放(ISO)标准,允许您表达有关XML文档中应存在的模式的断言。例如,您可以使用它来表达约束,例如:
A
存在,则禁止元素B
。如果A
和B
是兄弟姐妹,则可以使用XML架构中的xs:choice
来执行此操作,但如果这两个元素不是兄弟,则此方法在XML架构中不起作用。< / LI>
A
具有特定值的属性,则它必须包含子元素B
。A
必须等于元素B
和C
的总和。在您的具体示例中,我将假设imageSrc
是强制标记,您希望在“Cottage”类型的House上强制执行,并禁止其他类型。
表达这些断言的简单Schematron模式的一个例子是:
<schema xmlns="http://purl.oclc.org/dsdl/schematron">
<pattern>
<!-- Houses of type 'Cottage' must contain an imageSrc element -->
<rule context = "/root/House[type/text() = 'Cottage']">
<assert test = "imageSrc">Cottages must have an image</assert>
</rule>
<!-- Houses not of type 'Cottage' must not contain an imageSrc element -->
<rule context = "/root/House[type/text() != 'Cottage']">
<assert test = "not(imageSrc)">Non-cottages must not have an image</assert>
</rule>
</pattern>
</schema>
在这里,我将模式表达为两个单独的规则,分别针对您要求的两个部分。
每个rule
都有一个context
属性,这是一个XPath表达式。当此表达式的计算结果为true时,规则“触发”。因此,第一条规则触发House
元素,其中type
子元素的文本内容等于'Cottage'。
当规则触发时,然后通过评估test
元素的assert
属性来检查断言。同样,这是一个XPath表达式,但用于评估测试表达式的上下文节点是由rule
元素匹配的节点(在本例中为House
)。当测试表达式求值为true时,断言通过(即文档对于该断言是有效的)。如果它的计算结果为false,则断言失败。 assert
元素的文本内容通常是可以传递给最终用户的断言的人类可读描述。 Schematron还提供其他工具(称为“诊断”),以将其他技术消息链接到断言。
http://www.schematron.com/implementation.html提供了一个公开的基于XSLT的Schematron实现。典型的验证管道将涉及首先针对定义文档的基本结构要求的XML模式验证文档(例如元素层次结构,基数,数据类型,模式等)。然后,一旦文档通过了这个基本的验证级别,您就可以根据Schematron模式验证文档,以验证其他基于模式的约束。此管道可以以编程方式实现,也可以使用(例如)批处理文件,Ant脚本或XProc处理器实现。
答案 1 :(得分:0)
虽然XSD确实不支持这种行为,但你可以简单地定义两种House类型,一种是强制节点,另一种是没有。