XQuery:如何知道是否有双峰?

问题描述 投票:2回答:3

我有XML文件,每个<a>都有<b>element

我想使用XQuery编写查询以返回True或False

有一个称为<element>的元素。

每个<element>中有两个元素<a><b>

返回False:如果<a>的值与另一个元素中的另一个<a>的值相同,&&其中<b>的值不同

否则为True:每个元素的<a>值不同或有相似之处,但<b>值不同

例如

<root>
<element>
   <a>ttt</a>
   <b>tttsame</b>
</element>
<element>
   <a>ttt</a>
   <b>tttsame</b>
</element>
<element>
   <a/>
   <b>value</b>
</element>
<element>
   <a>rrr</a>
   <b>rrrvalue</b>
</element>
<element>
   <a>mmm</a>
   <b>rrrvalue</b>
</element>
<element>
   <a>mmm</a>
   <b>rrrvalue</b>
</element>
</root>

这个应该可以应该返回true

<root>
<element>
   <a>ttt</a>
   <b>ttt value</b>
</element>
<element>
   <a>ttt</a>
   <b>ttrdiff</b>
</element>
<element>
   <a/>
   <b>value</b>
</element>
<element>
   <a>mmm</a>
   <b>rrrvalue</b>
</element> 
</root>

不应该接受,因为ttt有两个不同的值应该返回false

xpath xquery
3个回答
2
投票

简单XPath 2.0

empty(
        (for $parentA-Dubled in /*/*[a = following-sibling::*/a]
           return
             empty($parentA-Dubled/following-sibling::*
                                        [$parentA-Dubled/a eq a and $parentA-Dubled/b ne b])
        )
        [not(.)]
      )

基于XSLT 2.0的验证:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/">
    <xsl:value-of select=
    "empty(
            (for $parentA-Dubled in /*/*[a = following-sibling::*/a]
              return
                empty($parentA-Dubled/following-sibling::*
                                         [$parentA-Dubled/a eq a and $parentA-Dubled/b ne b])
            )
             [not(.)]
          )
     "/>
    </xsl:template>
</xsl:stylesheet>

当将此转换应用于任何XML文档时,它将评估XPath表达式并输出该评估的结果

应用于第一个提供的XML文档时,会产生所需的正确结果:

true

当应用于第二个提供的XML文档时,再次产生想要的正确结果:

false

说明

此子表达式:

(for $parentA-Dubled in /*/*[a = following-sibling::*/a]
               return
                 empty($parentA-Dubled/following-sibling::*
                          [$parentA-Dubled/a eq a and $parentA-Dubled/b ne b])

评估为布尔值序列:true() / false()

true()为真时返回:

empty($parentA-Dubled/following-sibling::*
                          [$parentA-Dubled/a eq a and $parentA-Dubled/b ne b])

[这意味着,当true()没有其他$parentA-Dubled/a时,每次都会返回a$parentA-Dubled的后继同级的子代,其值与$parentA-Dubled/a相同,但值其b同级与$parentA-Dubled/b的值不同。

Tosuming:对于具有相同值的all true()个元素,它们的a兄弟姐妹也具有(所有b)相同值,则返回b

然后何时返回false()

[返回false()表示empty()返回false() -也就是说,至少有两个a元素具有相同的值,但是它们的b兄弟具有不同的值。

因此,上面的子表达式返回一个序列,例如:

true(), true(), true(), ..., true()-所有值均为true()

true(), true(), true(), ..., false), ..., true()-至少一个值是false()

原始问题要求我们在第一种情况下返回true(),在第二种情况下返回false()。>>

这很容易表示为:

empty($booleanSequence[. eq false()])-相当于简称:

empty($booleanSequence[not(.)])

现在,我们只需要用上面分析的第一个子表达式替换上面的表达式$booleanSequence

(for $parentA-Dubled in /*/*[a = following-sibling::*/a]
               return
                 empty($parentA-Dubled/following-sibling::*
                          [$parentA-Dubled/a eq a and $parentA-Dubled/b ne b])

因此,我们获得了解决原始问题的完整XPath表达式:

empty(
        (for $parentA-Dubled in /*/*[a = following-sibling::*/a]
           return
             empty($parentA-Dubled/following-sibling::*
                                        [$parentA-Dubled/a eq a and $parentA-Dubled/b ne b])
        )
        [not(.)]
      )

2
投票

您可以对a进行分组,然后检查任何一组中是否存在多个不同的b,例如使用


0
投票

尝试使用此XQuery代码仅获得<a>的一个不同项(未指定相应的<b>值;这里选择了第一个元素):

© www.soinside.com 2019 - 2024. All rights reserved.