2012-01-22 134 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:我提供了一个不同的解决方案 - 现在加工。 –