我有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 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(.)]
)
您可以对a
进行分组,然后检查任何一组中是否存在多个不同的b
,例如使用
尝试使用此XQuery代码仅获得<a>
的一个不同项(未指定相应的<b>
值;这里选择了第一个元素):