如何计算给定节点后的所有节点?

时间:2013-01-31 15:40:22

标签: xpath

问题

我正在尝试计算网站显示价格的不同货币的数量。

网站的主页允许用户从下拉列表中选择货币。

我正在尝试找到一个XPath表达式,它将计算下拉列表中的不同货币。

列表如下所示:

enter image description here

列表中的前四种货币是用户最常选择的货币。

还会显示按货币代码排序的完整货币列表。完整列表包含前四种货币的重复。

通过在下拉列表中添加禁用的空白选项,可以直观地分离“热门”列表和“完整”列表。

主页上用于创建列表的HTML如下所示:

<?xml version="1.0" encoding="UTF-8"?>

<select id="selCurrency" tabindex="122">
  <option value="GBP" selected="selected">Select your currency</option>
  <option value="GBP">GBP - £</option>
  <option value="EUR">EUR - €</option>
  <option value="PLN">PLN - zł</option>
  <option value="USD">USD - $</option>
  <option value="" disabled="disabled"/>
  <option value="AED">AED - د.إ.‏</option>
  <option value="AFN">AFN</option>
  <option value="ARS">ARS - $</option>
  <option value="AUD">AUD - $</option>
  <option value="BDT">BDT</option>
  <option value="BGN">BGN - лв.</option>
  <option value="BOB">BOB - Bs.</option>
  <!-- ... -->
</select>

为简洁起见,我删除了屏幕截图中看不到的元素。

尝试的解决方案

我的解决方案的想法是只选择空白分隔符后面的所有节点并计算它们。

此XPath表达式仅选择分隔符:

//*[@id="selCurrency"]/option[@value=""]

根据w3schools page on XPath axes,我可以使用以下兄弟轴来选择当前节点之后的所有兄弟节点。

按照示例,我尝试了以下表达式:

//*[@id="selCurrency"]/following-sibling::option[@value=""]

但这不会返回任何内容,或者是非法语法。我不确定是哪一个。

如何选择完整货币列表中的所有节点,然后对其进行计数?

2 个答案:

答案 0 :(得分:3)

您需要结合两次尝试才能获得正确的项目:

//*[@id="selCurrency"]/option[@value=""]/following-sibling::option

如果您想使用XPath来计算这些,那么这将是计算它们的公式:

count(//*[@id="selCurrency"]/option[@value=""]/following-sibling::option)

答案 1 :(得分:0)

JLRishe已经回答了提出的问题。

在问题文本中埋藏是对问题的更一般描述:

  

找到一个XPath表达式,它将计算下拉列表中的不同货币。

JLRishe的答案解决了这个问题,但依赖于元素的排序。对于习惯使用套装的人来说,这感觉太脆弱了。如果界面设计者删除了分隔符行,或者选择停止复制“完整”列表中的“热门”元素,则查询会产生误导性结果。

Dimitre Novatchev's help,我想出了

count(/select/option/@value[not(. = '') and not(. = ../following-sibling::option/@value)])

它过滤掉分隔符值并计算剩余的不同值。应用于我的示例时,输出为

7

我相信这是我想要解决的问题的更强大的解决方案。