XPath, чтобы получить элемент с самым высоким ID - PullRequest
12 голосов
/ 24 сентября 2010

Источник XML:

<documents>
    <document>
        <id>3</id>
    </document>
    <document>
        <id>7</id>
    </document>
    <document>
        <id>1</id>
    </document>
</documents>

Мне нужен элемент документа с наибольшим значением в его элементе id (поэтому <document><id>7</id></document> в примере). Я не могу изменить код C #, это XMLDocument.SelectSingleNode(...), я могу изменить только используемый XPath.

Есть ли что-то вроде documents/document[id=max(id)] или order by id descending, чтобы получить это?

Ответы [ 5 ]

27 голосов
/ 24 сентября 2010
documents/document[not(../document/id > id)]/id
11 голосов
/ 24 сентября 2010

Помимо правильного ответа Ника Джонс XPath 1.0, в XPath 2.0:

/documents/document[id = max(../document/id)]
2 голосов
/ 24 сентября 2010

Вы можете использовать оси preceding и following XPath, чтобы проверить, нет ли большего значения:

XmlDocument doc = new XmlDocument();
doc.LoadXml("<documents>"
    + "  <document><id>3</id></document>"
    + "  <document><id>7</id></document>"
    + "  <document><id>1</id></document>"
    + "</documents>");

var max = doc.SelectSingleNode(
    "/documents/document[not(id < preceding::document/id)
                         and not(id < following::document/id)]");

Если в документе несколько максимальных значений идентификатора, приведенный выше код вернет первое. Если вы хотите последний элемент с максимальным идентификатором, вы можете использовать

var max = doc.SelectSingleNode(
    "/documents/document[not(id < preceding::document/id) 
                         and not(id <= following::document/id)]");

Если вы хотите получить список со всеми элементами, имеющими максимальный идентификатор, вы можете использовать метод SelectNodes:

var maxList = doc.SelectNodes(
    "/documents/document[not(id < preceding::document/id) 
                         and not(id < following::document/id)]");

XSLT версия:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
      <root>
        <xsl:value-of 
             select="/documents/document/id[not(. &lt;= preceding::document/id) 
                     and not(. &lt;= following::document/id)]"/>
      </root>
    </xsl:template>
</xsl:stylesheet>
1 голос
/ 24 сентября 2010

Посмотри на эту ссылку. Используется функция math: max ().

Существует ссылка на источник для этой функции и объясняется, как ее можно реализовать

http://www.exslt.org/math/functions/max/index.html

Надеюсь, это поможет вам

0 голосов
/ 24 сентября 2010

К сожалению, ни XPath 1.0, ни XPath 2.0 не определяют функцию sort ().Однако большинство реализаций имеют сортировку.Например, <xsl:sort> доступно в реализациях XSLT, а DOM4J имеет метод сортировки по XPath.Я уверен, что в C # есть что-то похожее, но вам придется немного изменить код C #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...