2011-01-31 21 views
8

To jest mój XML.Jak sortować wartości za pomocą XPath

<root> 

<element> 
<title>Title .. </title> 
<val>2</val> 
<date>21/01/2011</date> 
</element> 

<element> 
<title>Title .. </title> 
<val>1</val> 
<date>21/01/2011</date> 
</element> 

<element> 
<title>Title .. </title> 
<val>2</val> 
<date>22/01/2011</date> 
</element> 

</root> 

Logika jest taka: Element węzły powinny być uporządkowane według val węzła i daty. Pierwsze Zamówienie musi być oparte na wartościach val oraz w obrębie tej sekwencji węzłów z wartością val. Powinny być wymienione według daty.

Czy ktoś wie, jak uzyskać posortowaną listę węzłów XML za pośrednictwem XPath?

Wszelkie pomysły?

+0

Wydaje się, że sama XPath nie obsługuje sortowania: https : //stackoverflow.com/questions/8480673/sort-with-xpath-not-xsl Nie wiesz, czy to prawda w przypadku najnowszych wersji XPath. –

Odpowiedz

9

Możesz użyć xsl:sort do sortowania pasujących węzłów. Umożliwi to sortowanie według elementu val. Jednak XPath 1.0 nie ma typu danych typu data. Rozsądnym rozwiązaniem tego problemu jest podzielenie daty na komponenty roku, miesiąca i dnia oraz sortowanie według każdego z osobna. Poniższa powinno załatwić sprawę:

<?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:copy> 
     <xsl:apply-templates> 
     <xsl:sort select="val" data-type="number" order="descending"/> 

     <!-- year sort --> 
     <xsl:sort select="substring(date,7,4)" data-type="number" /> 
     <!-- month sort --> 
     <xsl:sort select="substring(date,4,2)" data-type="number" /> 
     <!-- day sort --> 
     <xsl:sort select="substring(date,1,2)" data-type="number" />   
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Dzięki - Twoja usunięta odpowiedź też mi się podobała. Funkcja translate() była nieco sprytna ;-) – ColinE

+0

Nie działała, ponieważ liczby były tak duże jak liczba dni :) Zacząłem pisać podłańcuch, ale już to zrobiłeś. – Flack

+7

Jeśli jesteś odpowiedzialny za projekt XML (a nawet, jeśli nie jesteś ...), zawsze lepiej jest trzymać daty w formacie ISO RRRR-MM-DD niż jako dd/mm/rrrr lub mm/dd/rrrr . Pozwala uniknąć niejednoznaczności dla ludzkiego czytelnika i jest łatwiejsze do przetworzenia przez oprogramowanie. –

0

Wydaje się, że XPath 3.1 Oferty Sortowanie:

Podpisy

fn:sort($input as item()*) as item()* 
fn:sort($input as item()*, 
    $collation as xs:string?) as item()* 
fn:sort($input as item()*, 
    $collation as xs:string?, 
    $key as function(item()) as xs:anyAtomicType*) as item()* 

https://www.w3.org/TR/xpath-functions-31/#func-sort

Powiązane problemy