【问题标题】:XML Schema: Validate distinct pair of elementsXML Schema:验证不同的元素对
【发布时间】:2019-02-08 13:25:30
【问题描述】:

我尝试生成 XML 架构,以验证不应允许多个相同元素多次出现的 xml 文件。

下面应该有几个元素。在 each 下,必须有一对部分,并且这个组合应该是唯一的。

使用了 XSD 1.1 和 XPath 2.0,我尝试了几种解决方案,例如 count() eq count(distinct())、count() eq 1、every & previous-siblings。

尝试是这样的:

<xs:assert test="count( box/part[1]/@label/text() || box/part[2]/@label/text() ) 
                 eq count( distinct-values( box/part[1]/@label/text() ||
                                            box/part[2]/@label/text() ) )"/>

还有一个是这样的:

<xs:assert test="count(box) eq count(box[ not ( preceding-sibling::box/part[1]/[@label 
                                                =current()/part[1]/@label]  or
                                                preceding-sibling::box/part[2]/[@label 
                                                = current()/part[1]/@label] ) ])"/>

更具体地说,这应该是有效的:

<box_list>
    <box>
        <part label="aaa"/>
        <part label="bbb"/>
        <random_el id="8"/>
    </box>
    <box>
        <part label="ccc"/>
        <part label="iii"/>
        <random_el height="9"/>
    </box>
    <box>
        <part label="aaa"/>
        <part label="kkk"/>
        <random_el id="5"/>
    </box>
</box_list>

并且以下内容一定是无效的:

<box_list>
    <box>
        <part label="aaa"/>
        <part label="bbb"/>
        <random_el id="8"/>
    </box>
    <box>
        <part label="aaa"/>
        <part label="bbb"/>
        <random_el height="9"/>
    </box>
    <box>
        <part label="aaa"/>
        <part label="kkk"/>
        <random_el id="5"/>
    </box>
</box_list>

任何帮助将不胜感激!

【问题讨论】:

    标签: xml xsd-validation


    【解决方案1】:

    从你的问题中不清楚是否有一个盒子有零件(aaa,bbb)和另一个盒子有零件(bbb,aaa)。

    假设这是有效的,那么你可以使用count(box) = count(distinct-values(box/concat(part[1]/@label, part[2]/@label))

    请注意,@label/text() 不选择任何内容。属性节点没有子节点。

    【讨论】:

    • 非常感谢迈克尔!不幸的是,同一个 xml 中的 (aaa,bbb) 和 (bbb,aaa) 无效。有没有其他方法可以验证它?
    • 只有两部分,你可以使用distinct-values((part[1]/@label||part[2]/@label, part[2]/@label||part[1]/@label))。在更大的集合上进行任意排列是很棘手的;使用 XPath 3.1,您可以使用 fn:sort() 来规范化顺序。
    • 感谢凯先生的即时回复!最终我解决了我之前发布的问题。
    【解决方案2】:
    <xs:assert test="2*count(box) eq ( count( distinct-values((box/concat(part[1]/@label, part[2]/@label),
                                                               box/concat(part[2]/@label, part[1]/@label))) ) + 
                                       count( box[part[1]/@label eq part[2]/@label] ) )"/>
    

    【讨论】:

      猜你喜欢
      • 2021-08-24
      • 2012-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 2011-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多