Home > Software engineering >  Sorting xml by attribute value with an xslt
Sorting xml by attribute value with an xslt

Time:03-31

I am not very skilled at xslt but I am looking to sort my data in an xml by the value of the stat name attributes.

Here is what my data looks like:

<SeasonStatistics>
<Team name="X" id="000000">
<Player first_name="A">
<Stat name="STATCAT1">42</Stat>
<Stat name="STATCAT2">1</Stat>
<Stat name="STATCAT3">1</Stat>
</Player>
<Player first_name="B">
<Stat name="STATCAT1">187</Stat>
<Stat name="STATCAT2">1</Stat>
<Stat name="STATCAT3">15</Stat>
</Player>
<Player first_name="C">
<Stat name="STATCAT1">92</Stat>
<Stat name="STATCAT2">3</Stat>
<Stat name="STATCAT3">5</Stat>
</Player>
</Team>

Here is what the output should look like:

<SeasonStatistics>
<Team name="X" id="000000">
<Player first_name="B">
<Stat name="STATCAT1">187</Stat>
<Stat name="STATCAT2">1</Stat>
<Stat name="STATCAT3">15</Stat>
</Player>
<Player first_name="C">
<Stat name="STATCAT1">92</Stat>
<Stat name="STATCAT2">3</Stat>
<Stat name="STATCAT3">5</Stat>
</Player>
<Player first_name="A">
<Stat name="STATCAT1">42</Stat>
<Stat name="STATCAT2">1</Stat>
<Stat name="STATCAT3">1</Stat>
</Player>
</Team>

Here is what I tried but it did not seem to work.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  <xsl:strip-space elements="*" />
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Team">
    <xsl:copy>
        <xsl:apply-templates select="Player">
            <xsl:sort select="Stat"/>
                        <xsl:sort select="@STATCAT1" data-type="number" order="descending"/>
        </xsl:apply-templates>
    </xsl:copy>
        </xsl:template>
</xsl:stylesheet>

CodePudding user response:

Instead of:

  <xsl:template match="Team">
    <xsl:copy>
        <xsl:apply-templates select="Player">
            <xsl:sort select="Stat"/>
                        <xsl:sort select="@STATCAT1" data-type="number" order="descending"/>
        </xsl:apply-templates>
    </xsl:copy>
        </xsl:template>

try:

<xsl:template match="Team">
    <xsl:copy>
        <xsl:apply-templates select="Player">
            <xsl:sort select="Stat[@name='STATCAT1']" data-type="number" order="descending"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>
  • Related