注:以下信息假设使用的XPath 1.0。
下面的表达式返回具有最大id
值的元素(S):
/*/book[not(@id < preceding-sibling::book/@id) and
not(@id < following-sibling::book/@id)]
注意,这是略有不同@ timbooo在这个问题的答案时,有与重复这将返回多个元素相同的最大值(@ timbooo's将不返回)。如果你在这种情况下只需要一个元素,那么你需要一个解决策略。要选择在文档顺序第一个这样的元素,使用:
/*/book[not(@id < preceding-sibling::book/@id) and
not(@id < following-sibling::book/@id)][1]
要选择最后一个,使用此:
/*/book[not(@id < preceding-sibling::book/@id) and
not(@id < following-sibling::book/@id)][last()]
这种做法是非常低效的(O(n^2)
),因为它需要你去比较每个元素到其他每个潜在的最大值。出于这个原因,最好使用主机编程语言来选择最大元素。只需首先选择所有book
元素,然后从该列表中选择最大值。这很可能是一种线性操作(O(n)
),对于非常大的文档,这将显着加快。例如,在Java(JAXP),你可能做这样的:
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate("/*/book", doc,
XPathConstants.NODESET);
Node max = nodes.item(0);
for (int i = 0; i < nodes.getLength(); i++) {
int maxval = Integer.parseInt(max.getAttributes()
.getNamedItem("id").getNodeValue());
int curval = Integer.parseInt(nodes.item(i).getAttributes()
.getNamedItem("id").getNodeValue());
if (curval >= maxval)
max = nodes.item(i);
}
System.out.println(max.getAttributes().getNamedItem("name"));
注意,这仅仅是一个示范;务必在适当的地方包含空值检查。
+1,菠萝:P – 2012-01-02 14:35:06
执行XPath的主机语言是什么?如果您使用的是XPath 1.0(它没有'max'函数),那么首先选择所有元素并在您的PL中查找最大值可能会更快。 – 2012-01-03 01:33:32
我使用Perl 5.10。 – HerbSpiral 2012-01-03 08:53:24