2011-01-31 3 views
8

Это мой XML.Как отсортировать значения через 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> 

Логики заключается в следующем: узлах элемента должны быть ранжированы в соответствии с узлом Вала и датой. Первый порядок должен основываться на val и внутри этой последовательности узлов с значением val. Они должны быть указаны по дате.

Кто-нибудь знает, как получить отсортированный список узлов XML через XPath?

Любые идеи?

+0

Кажется, что само по себе XPath не поддерживает сортировку: по протоколу HTTPS : //stackoverflow.com/questions/8480673/sort-with-xpath-not-xsl Не уверен, что это верно для новейших версий XPath. –

ответ

9

Вы можете использовать xsl:sort для сортировки совпадающих узлов. Это позволит вам отсортировать по элементу val. Однако XPath 1.0 не имеет типа данных даты. Разумным решением этой проблемы является разделение вашей даты на ее год, месячные и дневные компоненты и сортировка по каждому отдельно. Ниже следует сделать трюк:

<?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

Спасибо - ваш удаленный ответ тоже понравился мне. Функция translate() была немного хитрой ;-) – ColinE

+0

Это не сработало из-за того, что числа были такими же большими, как число дней :) Я начал писать подстроку, но вы уже это сделали. – Flack

+7

Если вы отвечаете за дизайн XML (или даже если вы не ...), всегда лучше хранить даты в формате ISO YYYY-MM-DD, а не как dd/mm/yyyy или mm/dd/yyyy , Это позволяет избежать двусмысленности для читателя, и программное обеспечение легче обрабатывать. –

0

Это кажется, что XPath 3.1 предложения сортировка:

Подписи

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

Смежные вопросы