xsl multiple sort hierarchy

2019-08-24 01:24发布

I have an XML structure which looks like this -

<Root>
  <name rank = "1">ABC
     <name rank ="1">BCD</name>
  </name>
  <name rank ="0">XYZ
     <name rank ="1">BCD</name>
     <name rank ="3">YYZ</name>
     <name rank ="0">FEG</name>
     <name rank ="0">DEG</name>         
  </name>
</Root>

I want to transform this XML by making a copy of it, preserving the hierarchy, and sort it in the order (1) By Rank (ascending) (2) If Ranks are equal, sort it by name(ascending)

After transformation, the structure should look like this.

<Root>      
      <name rank ="0">XYZ
         <name rank ="0">DEG</name>
         <name rank ="0">FEG</name>
         <name rank ="1">BCD</name>
         <name rank ="3">YYZ</name>         
      </name>
      <name rank = "1">ABC
         <name rank ="1">BCD</name>
      </name>
 </Root>

I have the following XSL, which does not preserve the heirarchy or gives me the correct sort. Can someone please help me out? This is my first time working with XSL and would appreciate any help or pointers in the right direction.

<xsl:template match="/*">

    <xsl:copy>
    <xsl:for-each select="//name">
        <xsl:sort select="@rank" data-type="number" order="ascending"/>
        <xsl:sort select="name" order="ascending" />
        <xsl:copy-of select="."/>
    </xsl:for-each> 
    </xsl:copy>
  </xsl:template>

标签: xml xslt
1条回答
SAY GOODBYE
2楼-- · 2019-08-24 02:25

This transformation:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
  <Root>
    <xsl:apply-templates select="name">
     <xsl:sort select="@rank" data-type="number"/>
     <xsl:sort/>
    </xsl:apply-templates>
  </Root>
 </xsl:template>

 <xsl:template match="name">
  <name rank="{@rank}">
    <xsl:copy-of select="text()"/>
    <xsl:apply-templates select="name">
     <xsl:sort select="@rank" data-type="number"/>
     <xsl:sort/>
    </xsl:apply-templates>
  </name>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<Root>
  <name rank = "1">ABC
     <name rank ="1">BCD</name>
  </name>
  <name rank ="0">XYZ
     <name rank ="1">BCD</name>
     <name rank ="3">YYZ</name>
     <name rank ="0">FEG</name>
     <name rank ="0">DEG</name>
  </name>
</Root>

produces the wanted, correct result:

<Root>
    <name rank="0">XYZ
        <name rank="0">DEG</name>
        <name rank="0">FEG</name>
        <name rank="1">BCD</name>
        <name rank="3">YYZ</name></name>
    <name rank="1">ABC
        <name rank="1">BCD</name></name>
</Root>

Explanation:

Using two xsl:sort instructions. The priority of the sort operations corresponds to the document order of the respective xsl:sort instructions.

查看更多
登录 后发表回答