2010-09-24 10 views
12

XML Źródło:XPath uzyskać elementu z najwyższym ID

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

muszę dokumentu elementu o najwyższej wartości w swoim id-elementu (tak <document><id>7</id></document> w przykładzie). Nie mogę zmienić kodu C#, to jest XMLDocument.SelectSingleNode(...), mogę tylko modyfikować używane XPath.

Czy jest coś takiego, jak documents/document[id=max(id)] lub jak order by id descending, aby go zdobyć?

Odpowiedz

24
documents/document[not(../document/id > id)] 
+2

+1 Dla najkrótszej i poprawnej maksymalnej ekspresji XPath 1.0, poza złożonością cuadratic ... –

+0

dzięki, świetne rozwiązanie, powinieneś zdobyć za to punkty bonusowe! – Hinek

+2

Sprytne rozwiązanie! –

1

Mieć rozkosz dla tego łącza. Używa funkcji matematycznej: max().

Jest link do źródła dla tej funkcji i wyjaśnia, w jaki sposób może on być realizowany

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

nadzieję, że to pomaga

+0

I po wdrożeniu tego można zrobić coś takiego:/dokumenty/dokument/id [numer (child :: text()) Restuta

+0

Jak daleko jak widzę, jest obsługiwany przez kilka procesorów XSLT, ale nie przez .NET ... czy czegoś brakuje? – Hinek

+0

@Restuts, potrzebuję węzła dokumentu, nie powinno to być bardziej jak:/documents/document [numer (id/child :: text()) = matematyka: max (numer (id/child :: text()))] – Hinek

0

Niestety ani XPath 1.0 lub XPath 2.0 określić rodzaj() funkcjonować. Jednak większość implementacji ma sortowanie. Na przykład <xsl:sort> jest dostępny w implementacjach XSLT, a DOM4J ma sortowanie według metody XPath. Jestem pewien, że jest coś podobnego w C#, ale musiałbyś trochę zmienić kod C#.

2

Można użyć preceding i following Osie XPath, by sprawdzić, czy nie ma większej wartości:

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)]"); 

Jeśli istnieje kilka maksymalne wartości id w dokumencie powyższy kod zwróci pierwszy. Jeśli chcesz ostatni element o maksymalnej ID można użyć

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

Jeśli chcesz uzyskać listę wszystkich elementów o maksymalnej id można użyć metody SelectNodes: wersja

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> 
+0

Czy to nie tylko da ci pierwszą, która przyszła, jest wyższa od poprzedniej i tej, która była po nim? – jimplode

+0

Przepraszam, mój błąd. – jimplode

11

Poza Nick Jones XPath 1.0 prawidłową odpowiedź, w XPath 2.0:

/documents/document[id = max(../document/id)] 
Powiązane problemy