Примечание: Следующая информация предполагает использование XPath 1.0.
Следующее выражение возвращает элемент (ы) с наибольшим значением id
:
/*/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"));
Обратите внимание, что это просто демонстрация; при необходимости обязательно включите нулевые проверки.