2016-11-18 69 views
0

我有以下輸入XML:如何進行分級XSL排序?

<?xml version="1.0" encoding="UTF-8"?> 
<soldiers> 
    <soldier> 
     <name>John</name> 
     <supervisor>Marcus</supervisor> 
    </soldier> 
    <soldier> 
     <name>Marcus</name> 
     <supervisor>Mike</supervisor> 
    </soldier> 
    <soldier> 
     <name>Frank</name> 
     <supervisor>Marcus</supervisor> 
    </soldier> 
    <soldier> 
     <name>Mike</name> 
     <supervisor>Anna</supervisor> 
    </soldier> 
</soldiers> 

現在我正在尋找一種方式排序此XML hierarchicaly基於主管標籤。什麼是最高效的方式來做到這一點?給出的例子的結果應該如下所示:

<?xml version="1.0" encoding="UTF-8"?> 
<soldiers> 
    <soldier> 
     <name>Mike</name> 
     <supervisor>Anna</supervisor> 
    </soldier> 
    <soldier> 
     <name>Marcus</name> 
     <supervisor>Mike</supervisor> 
    </soldier> 
    <soldier> 
     <name>John</name> 
     <supervisor>Marcus</supervisor> 
    </soldier> 
    <soldier> 
     <name>Frank</name> 
     <supervisor>Marcus</supervisor> 
    </soldier> 
</soldiers> 

因此,邁克沒有在這裏列出的主管,因此他位居榜首。馬庫斯的主管是邁克,因此他在邁克。約翰和弗蘭克的主管是馬庫斯,因此他們處於最底層。

+0

您的處理器是否支持XSLT 2.0? –

+0

是的,它支持XSLT 1.0 – BenTreeser

+0

不是一個好的答案。請再次閱讀該問題。 –

回答

1

可以使用key跟隨引用:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

    <xsl:output indent="yes"/> 

    <xsl:key name="ref" match="soldier" use="supervisor"/> 

    <xsl:template match="soldiers"> 
     <xsl:copy> 
      <xsl:apply-templates select="soldier[not(supervisor = ../soldier/name)]"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="soldier"> 
     <xsl:copy-of select="."/> 
     <xsl:apply-templates select="key('ref', name)"/> 
    </xsl:template> 
</xsl:transform> 

基於@ michael.hor257k的評論,你也許更願意

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" 
    xmlns:mf="http://example.com/mf" exclude-result-prefixes="mf"> 

    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:key name="ref" match="soldier" use="supervisor"/> 

    <xsl:variable name="main-root" select="/"/> 

    <xsl:function name="mf:refs" as="element(soldier)*"> 
     <xsl:param name="input" as="element(soldier)*"/> 
     <xsl:copy-of select="$input"/> 
     <xsl:sequence select="if (key('ref', $input/name, $main-root)) then mf:refs(key('ref', $input/name, $main-root)) else()"/> 
    </xsl:function> 

    <xsl:template match="soldiers"> 
     <xsl:copy> 
      <xsl:sequence select="mf:refs(soldier[not(supervisor = ../soldier/name)])"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:transform> 

它使用相同的密鑰,但每個輸出水平完全首先在遞交到下一個級別之前。

相關問題