2012-01-22 152 views
1

對不起,我的英語。 我需要這個XML數據的節點XSLT排序子節點

<root> 
    <section id="1"> 
    <news-item id="1" pub-date="2012-01-03" /> 
    <news-item id="2" pub-date="2012-01-04" /> 
    <news-item id="3" pub-date="2011-12-21" /> 
    </section> 

    <section id="2"> 
    <news-item id="4" pub-date="2012-01-05" /> 
    <news-item id="5" pub-date="2012-01-06" /> 
    <news-item id="6" pub-date="2012-01-07" /> 
    </section> 

    <section id="3"> 
    <news-item id="7" pub-date="2012-02-10" /> 
    <news-item id="8" pub-date="2012-02-11" /> 
    <news-item id="9" pub-date="2012-02-12" /> 
    </section> 
</root> 

這個

<root> 
    <section id="3"> 
    <news-item id="9" pub-date="2012-02-12" /> 
    <news-item id="8" pub-date="2012-02-11" /> 
    <news-item id="7" pub-date="2012-02-10" /> 
    </section> 

    <section id="2"> 
    <news-item id="6" pub-date="2012-01-07" /> 
    <news-item id="5" pub-date="2012-01-06" /> 
    <news-item id="4" pub-date="2012-01-05" /> 
    </section> 

    <section id="1"> 
    <news-item id="2" pub-date="2012-01-04" /> 
    <news-item id="1" pub-date="2012-01-03" /> 
    <news-item id="3" pub-date="2011-12-21" /> 
    </section> 
</root> 

即我需要在前排序新聞條目元素通過酒館最新的部分,然後排序部分排序 element by max pub-date in news-item。 (有lastes新聞的部分必須在最上面)。

非常感謝!

+0

P.S我用微軟XLST處理器 – epifun

+0

你有什麼這麼遠嗎?這個網站不是「請爲我做」的東西。 – Lucero

+0

我在這個問題上工作了很多天,無法找到解決方案。我最後的解決方案http://codepaste.ru/9115/工作的工作。這是排序內部節點的權利,但外排節點按排序前排序 – epifun

回答

2

這是你pastebin有固定的名稱和不同的排序爲部分:

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

<xsl:template match="section"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates select="news-item"> 
      <xsl:sort select="@pub-date" data-type="text" order="descending" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="root"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:variable name="sectionOrder"> 
      <xsl:text>|</xsl:text> 
      <xsl:for-each select="section/news-item"> 
       <xsl:sort select="@pub-date" data-type="text" order="descending" /> 
       <xsl:value-of select="generate-id(..)"/> 
       <xsl:text>|</xsl:text> 
      </xsl:for-each> 
     </xsl:variable> 
     <xsl:apply-templates select="section"> 
      <xsl:sort select="string-length(substring-before($sectionOrder, concat('|',generate-id(),'|')))" data-type="number" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 

在引擎收錄的名稱不匹配(newsitemnews-itempubdatepub-date),所以我固定的。我得到的輸出似乎是正確的(也與您在您的評論添加的測試用例):

<root> 
    <section id="2"> 
     <news-item id="7" pub-date="2222-12-22" /> 
     <news-item id="6" pub-date="2012-01-07" /> 
     <news-item id="5" pub-date="2012-01-06" /> 
     <news-item id="4" pub-date="2012-01-05" /> 
    </section> 
    <section id="3"> 
     <news-item id="10" pub-date="2012-02-12" /> 
     <news-item id="9" pub-date="2012-02-11" /> 
     <news-item id="8" pub-date="2012-02-10" /> 
    </section> 
    <section id="1"> 
     <news-item id="2" pub-date="2012-01-04" /> 
     <news-item id="1" pub-date="2012-01-03" /> 
     <news-item id="3" pub-date="2011-12-21" /> 
    </section> 
</root> 
+0

輸出錯誤。嘗試添加作爲

中的最後一個元素,例如 – epifun

+1

@epifun,我編輯了我的代碼。請試試這個。 – Lucero

+0

thx!看起來不錯! – epifun

0

的替代,有些簡單,2通液(無xsl:variable,沒有generate-id(),沒有豎線分隔

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
exclude-result-prefixes="msxsl"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="vrtfPass1"> 
    <xsl:apply-templates mode="pass1"/> 
</xsl:variable> 

<xsl:template match="/*"> 
    <root> 
    <xsl:for-each select= 
    "msxsl:node-set($vrtfPass1)/*/*"> 
    <xsl:sort select="*[1]/@pub-date" order="descending"/> 
     <xsl:copy-of select="."/> 
    </xsl:for-each> 
    </root> 
</xsl:template> 

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

<xsl:template match="section" mode="pass1"> 
    <section id="{@id}"> 
    <xsl:apply-templates select="*" mode="pass1"> 
    <xsl:sort select="@pub-date" order="descending"/> 
    </xsl:apply-templates> 
    </section> 
</xsl:template> 
</xsl:stylesheet> 

當在下面的XML文檔施加(基於所提供的,但變得更「有趣):值,但使用msxsl:node-set()

<root> 
    <section id="1"> 
     <news-item id="1" pub-date="2012-01-03" /> 
     <news-item id="2" pub-date="2012-01-04" /> 
     <news-item id="3" pub-date="2011-12-21" /> 
    </section> 
    <section id="2"> 
     <news-item id="4" pub-date="2012-01-05" /> 
     <news-item id="5" pub-date="2012-01-06" /> 
     <news-item id="6" pub-date="2012-01-07" /> 
     <news-item id="7" pub-date="2222-12-22" /> 
    </section> 
    <section id="3"> 
     <news-item id="7" pub-date="2012-02-10" /> 
     <news-item id="8" pub-date="2012-02-11" /> 
     <news-item id="9" pub-date="2012-02-12" /> 
    </section> 
</root> 

想要的,正確的結果產生

<root> 
    <root> 
     <section id="2"> 
     <news-item id="7" pub-date="2222-12-22"/> 
     <news-item id="6" pub-date="2012-01-07"/> 
     <news-item id="5" pub-date="2012-01-06"/> 
     <news-item id="4" pub-date="2012-01-05"/> 
     </section> 
     <section id="3"> 
     <news-item id="9" pub-date="2012-02-12"/> 
     <news-item id="8" pub-date="2012-02-11"/> 
     <news-item id="7" pub-date="2012-02-10"/> 
     </section> 
     <section id="1"> 
     <news-item id="2" pub-date="2012-01-04"/> 
     <news-item id="1" pub-date="2012-01-03"/> 
     <news-item id="3" pub-date="2011-12-21"/> 
     </section> 
    </root> 
</root> 
+0

沒有按預期工作......在第2部分的輸入中添加以下內容:'' - 現在第2部分應該位於輸出的頂部,這與您的解決方案不同。 – Lucero

+0

@Lucero:我提供了一個不同的解決方案 - 現在加工。 –