我正在尝试计算与查询匹配的每个元素的特定属性(例如@root)的每个值的出现次数。其中一些匹配元素没有属性,但我也要计算它们(也就是列出没有属性的匹配元素的数量)
目前我使用它,但这与没有root
属性的节点不匹配。计数由应用程序完成,这允许我显示中间结果。
//node[@rel='su']/@root
我想要像
这样的东西 //node[@rel='su']/string(if .[@root] then @root else 'fallback-value')
查询是针对Berkeley DB XML运行的,因此XPath2和XQuery也可能用于解决此问题。
编辑:为了澄清,我正在寻找一个查询,它将@root属性的不存在视为一种特殊情况;即好像该属性确实存在并且具有'后备值'作为值。
答案 0 :(得分:1)
试试这个:
//node[@rel='su']/(@root/string(), 'no-value')[1]
遵循误解问题的原始答案
为什么不使用
//node[@rel='su']
然后?它将匹配具有node
属性的@root
元素和不具有node
属性的元素。
鉴于@root
最多只能有一个{{1}}属性,计算节点就足够了。
答案 1 :(得分:1)
这可以使用XQuery轻松完成。首先,在执行备用策略时收集匹配值:
let $matches := //node[@rel='su']/(data(@root), '')[1]
以上是对您问题中所表达的表达的略微纠正的重新表述。但请注意,它将使用零长度值处理根属性,与非现有根属性相同。
然后按不同的值进行分组,并计算每个组的出现次数:
for $value in distinct-values($matches)
let $count := count($matches[. = $value])
return <value count="{$count}">{$value}</value>
当应用于此输入时,
<x>
<node rel="su" root="A"/>
<node rel="su" root="A"/>
<node rel="su" root="B"/>
<node rel="su" root=""/>
<node rel="su"/>
<node rel="su"/>
</x>
结果可能是
<value count="2">A</value>
<value count="1">B</value>
<value count="3"/>
要强制执行结果的特定顺序,请添加order by
子句:
for $value in distinct-values($matches)
let $count := count($matches[. = $value])
order by $value
return <value count="{$count}">{$value}</value>
答案 2 :(得分:0)
这个怎么样?
//node[@rel='su' and not(@root)]
这应匹配没有root
属性的节点。
答案 3 :(得分:0)
使用强>:
concat('Having @root: ', count(//node[@rel='su']/@root ),
', Not having @root: ', count(//node[@rel='su'][not(@root)]),
', Having @root occur ',
floor(count(//node[@rel='su']/@root ) div count(//node[@rel='su']) * 100),
'% of the time.'
)
基于XSLT的验证:
<xsl:stylesheet version="1.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=
"concat('Having @root: ', count(//node[@rel='su']/@root ),
', Not having @root: ', count(//node[@rel='su'][not(@root)]),
', Having @root occur ',
floor(count(//node[@rel='su']/@root ) div count(//node[@rel='su']) * 100),
'% of the time.'
)
"/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下XML文档:
<t>
<node rel="su" root="2"/>
<node rel="su" root="1"/>
<node rel="su" />
<node rel="su" root="4"/>
<node rel="su" root="5"/>
<node rel="su" />
<node rel="su" root="7"/>
<node rel="su" root="8"/>
<node rel="su" />
<node rel="su" />
</t>
产生了想要的正确结果:
Having @root: 6, Not having @root: 4, Having @root occur 60% of the time.