使用XPath中的contains()函数和count()函数

7

我正在处理以下(次优)XML:

<a>
  <b>
    <c>X:1 Y:0</c>
    <c>X:1 Y:0</c>
    <c>X:2 Y:0</c>
  </b>
  <b>
    <c>X:1 Y:0</c>
    <c>X:2 Y:0</c>
  </b>
</a>

我想使用XPath来计算包含X:1<c>节点数:

count(contains(/a/b/c, 'X:1'))

然而,这会返回一个错误,而不是期望的计数3。我错在哪了?

2
这是其中一种情况,我倾向于建议使用样式表对XML进行预处理,将这些元素扩展为<c><X>1</X><Y>0</Y></c>等,然后处理此类数据变得微不足道。如果这只是一次性任务,那么可能不值得,但如果您需要经常执行此操作,则绝对值得考虑先将数据转换为更可用的形式。 - Flynn1179
2个回答

11

这不是使用contains()的方法。请尝试:

count(/a/b/c[contains(., 'X:1')])

@gjb, @Phil 更像是:“这不是使用count()的方式”,因为问题在于count()需要一个节点集作为参数,但contains()返回一个布尔值。 - jasso
@jasso contains() 函数期望第一个参数为字符串,而不是节点集合,因此实际上存在两个问题。 - Phil
1
@Phil 其实在你的例子中,contains() 的第一个参数也是一个节点集。这里的主要点是XPath规范明确规定了参数会被转换为函数所需的类型,如果一个参数不能被转换为所需的类型,则会出现错误。contains() 成功执行,但 count() 失败,因为一个不是节点集类型的参数无法被转换为节点集类型。 - jasso
1
有趣的是...当我对OP提供的样本数据运行count(...)命令时,我得到了3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 - JESii

3

可能会更高效一些(如果提供的XML文档中展示的属性不是偶然的):

count(/a/b/c[starts-with(., 'X:1')])

谢谢你的建议,但我担心顺序有时可能会变化。 - gjb
如果是这样,最好提供一个更好的XML示例来证明这一点。 - Dimitre Novatchev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接