Want more features on Pastebin? Sign Up, it's FREE!
Guest

Sorting node attributes and keeping structure in XSLT

By: a guest on May 31st, 2011  |  syntax: XML  |  size: 3.20 KB  |  views: 56  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  2. <xsl:output method="xml" indent="yes"/>
  3. <xsl:strip-space elements="*"/>
  4.  
  5. <!-- copy all other nodes -->
  6. <xsl:template match="node() | @*">
  7.     <xsl:copy>
  8.         <xsl:apply-templates select="node() | @*"/>
  9.     </xsl:copy>
  10. </xsl:template>
  11.  
  12. <!-- find every list element which has a preceding non-list element -->
  13. <xsl:template match="list[not(preceding-sibling::*[1][self::list])]">
  14.                 <!-- now walk recursive through all lists -->
  15.         <xsl:apply-templates select="self::list" mode="recurse">
  16.             <xsl:with-param name="level1_margin" select="@margin"/>
  17.             <xsl:with-param name="level" select="1"/>
  18.        </xsl:apply-templates>
  19. </xsl:template>
  20.  
  21. <!-- remove other list elements, because they are recursive processed -->
  22. <xsl:template match="list"/>
  23.  
  24. <!-- remove @margin from list -->
  25. <xsl:template match="list/@margin"/>
  26.  
  27. <!-- go recursive through all following lists -->
  28. <xsl:template match="list" mode="recurse">
  29.     <xsl:param name="level1_margin" select="0"/>
  30.     <xsl:param name="level" select="1"/>
  31.        
  32.     <xsl:variable name="nextStep" select="self::list/following-sibling::*[1][self::list]"/>
  33.    
  34.     <!-- create current list element with its level -->
  35.     <xsl:apply-templates select="self::list" mode="create">
  36.         <xsl:with-param name="level" select="$level"/>
  37.     </xsl:apply-templates>
  38.    
  39.     <xsl:if test="$nextStep">
  40.         <xsl:choose>
  41.                 <!-- new start margin/point for level 1 -->
  42.                 <xsl:when test="($nextStep/@margin &lt;= $level1_margin) or ($nextStep/@margin &lt; @margin and $level = 2)">
  43.                         <xsl:apply-templates select="$nextStep" mode="recurse">
  44.                                 <xsl:with-param name="level1_margin" select="$nextStep/@margin"/>
  45.                                 <xsl:with-param name="level" select="1"/>
  46.                         </xsl:apply-templates>
  47.                 </xsl:when>
  48.                 <!-- -1 -->
  49.                 <xsl:when test="$nextStep/@margin &lt; @margin and $level &gt; 1">
  50.                         <xsl:apply-templates select="$nextStep" mode="recurse">
  51.                                 <xsl:with-param name="level1_margin" select="$level1_margin"/>
  52.                                 <xsl:with-param name="level" select="$level - 1"/>
  53.                         </xsl:apply-templates>
  54.                 </xsl:when>
  55.                 <!-- +1 -->
  56.                 <xsl:when test="$nextStep/@margin &gt; @margin">
  57.                         <xsl:apply-templates select="$nextStep" mode="recurse">
  58.                                 <xsl:with-param name="level1_margin" select="$level1_margin"/>
  59.                                 <xsl:with-param name="level" select="$level + 1"/>
  60.                         </xsl:apply-templates>
  61.                 </xsl:when>
  62.                 <!-- +-0 -->
  63.                 <xsl:otherwise>
  64.                         <xsl:apply-templates select="$nextStep" mode="recurse">
  65.                                 <xsl:with-param name="level1_margin" select="$level1_margin"/>
  66.                                 <xsl:with-param name="level" select="$level"/>
  67.                         </xsl:apply-templates>
  68.                 </xsl:otherwise>                                               
  69.         </xsl:choose>
  70.     </xsl:if>
  71. </xsl:template>
  72.  
  73. <!-- create list element with level attribute -->
  74. <xsl:template match="list" mode="create">
  75.         <xsl:param name="level"/>
  76.     <list>
  77.         <xsl:attribute name="level">
  78.                 <xsl:value-of select="$level"/>
  79.         </xsl:attribute>
  80.         <xsl:apply-templates select="@*"/>
  81.         <xsl:apply-templates/>
  82.     </list>
  83. </xsl:template>
  84.  
  85. </xsl:stylesheet>
clone this paste RAW Paste Data