1

I want to sort an XML element by his children elements:

    <?xml version="1.0" encoding="utf-8"?>
<declaratieUnica luna_r="1" an_r="2011" d_rec="0" nume_declar="aa" prenume_declar="bb" functie_declar="contabil" xmlns="mfp:anaf:dgti:declaratie_unica:declaratie:v1">
  <angajator cif="15548207" rgCom="J40/8813/2003" caen="5221" den="CNCFR CFR" adrSoc="BUCURESTI,str.PIATA GARII DE NORD nr.1" telSoc="              0" faxSoc="              0" adrFisc="aaa" telFisc="123" faxFisc="4567" mailFisc="[email protected]" casaAng="_T" tRisc="0.297" dat="1" totalPlata_A="1830">
    <angajatorA A_codOblig="412" A_codBugetar="5502XXXXXX" A_datorat="444" A_deductibil="0" A_plata="444" />
    <angajatorA A_codOblig="411" A_codBugetar="5502XXXXXX" A_datorat="879" A_deductibil="0" A_plata="879" />   
  </angajator>
  <asigurat idAsig="1" cnpAsig="1610830297298" numeAsig="BUCUR" prenAsig="ION" dataAng="01.01.2011" casaSn="_B" asigCI="1" asigSO="1">
    <coAsigurati tip="S" cnp="2680502297316" nume="BUCUR" prenume="MARIA" />
    <asiguratD D_1="B1114" D_2="578" D_5="01.12.2010" D_6="01.12.2010" D_7="11.12.2010" D_9="01" D_10="2" D_14="5" D_15="5" D_16="10" D_17="15685" D_18="131" D_19="119.7328" D_20="449" D_21="449" />
    <asiguratB1 B1_1="1" B1_2="0" B1_3="N" B1_4="8" B1_5="0" B1_6="168" B1_7="0" B1_8="0" B1_9="0" B1_10="1360" B1_15="11" />
    <asiguratB2 B2_1="0" B2_2="11" B2_3="0" B2_4="0" B2_5="911" B2_6="0" B2_7="0" />
    <asiguratB3 B3_1="10" B3_2="0" B3_3="0" B3_4="0" B3_5="0" B3_6="10" B3_7="337" B3_8="0" B3_9="0" B3_10="0" B3_11="337" B3_12="449" B3_13="449" />
    <asiguratB4 B4_1="11" B4_2="0" B4_3="1360" B4_4="7" B4_5="911" B4_6="50" B4_7="1248" B4_8="131" B4_14="0" />
  </asigurat>
  <asigurat idAsig="2" cnpAsig="1790228297307" numeAsig="ADET" prenAsig="FLORIN" dataAng="01.01.2011" casaSn="_B" asigCI="1" asigSO="1">
    <coAsigurati tip="S" cnp="2790427297338" nume="ADET" prenume="ALINA IOANA" />
    <asiguratD D_1="BBBZ" D_2="014578" D_5="01.12.2010" D_6="01.12.2010" D_7="11.12.2010" D_9="01" D_10="1" D_14="4" D_15="0" D_16="4" D_17="14573" D_18="131" D_19="111.2443" D_20="445" D_21="0" />
    <asiguratB1 B1_1="1" B1_2="0" B1_3="N" B1_4="8" B1_5="0" B1_6="168" B1_7="0" B1_8="0" B1_9="0" B1_10="1740" B1_15="17" />
    <asiguratB2 B2_1="0" B2_2="17" B2_3="0" B2_4="0" B2_5="1295" B2_6="0" B2_7="0" />
    <asiguratB3 B3_1="4" B3_2="0" B3_3="0" B3_4="0" B3_5="0" B3_6="4" B3_7="135" B3_8="0" B3_9="0" B3_10="0" B3_11="135" B3_12="445" B3_13="0" />
    <asiguratB4 B4_1="17" B4_2="0" B4_3="1740" B4_4="9" B4_5="1295" B4_6="71" B4_7="1430" B4_8="150" B4_14="0" />
  </asigurat>  
</declaratieUnica>

Must be

<?xml version="1.0" encoding="utf-8"?>
<declaratieUnica luna_r="1" an_r="2011" d_rec="0" nume_declar="aa" prenume_declar="bb" functie_declar="contabil" xmlns="mfp:anaf:dgti:declaratie_unica:declaratie:v1">
  <angajator cif="15548207" rgCom="J40/8813/2003" caen="5221" den="CNCFR CFR" adrSoc="BUCURESTI,str.PIATA GARII DE NORD nr.1" telSoc="              0" faxSoc="              0" adrFisc="aaa" telFisc="123" faxFisc="4567" mailFisc="[email protected]" casaAng="_T" tRisc="0.297" dat="1" totalPlata_A="1830">
    <angajatorA A_codOblig="412" A_codBugetar="5502XXXXXX" A_datorat="444" A_deductibil="0" A_plata="444" />
    <angajatorA A_codOblig="411" A_codBugetar="5502XXXXXX" A_datorat="879" A_deductibil="0" A_plata="879" />   
  </angajator>
  <asigurat idAsig="1" cnpAsig="1610830297298" numeAsig="BUCUR" prenAsig="ION" dataAng="01.01.2011" casaSn="_B" asigCI="1" asigSO="1">
     <coAsigurati tip="S" cnp="2680502297316" nume="BUCUR" prenume="MARIA" />
    <asiguratB1 B1_1="1" B1_2="0" B1_3="N" B1_4="8" B1_5="0" B1_6="168" B1_7="0" B1_8="0" B1_9="0" B1_10="1360" B1_15="11" />
    <asiguratB2 B2_1="0" B2_2="11" B2_3="0" B2_4="0" B2_5="911" B2_6="0" B2_7="0" />
    <asiguratB3 B3_1="10" B3_2="0" B3_3="0" B3_4="0" B3_5="0" B3_6="10" B3_7="337" B3_8="0" B3_9="0" B3_10="0" B3_11="337" B3_12="449" B3_13="449" />
    <asiguratB4 B4_1="11" B4_2="0" B4_3="1360" B4_4="7" B4_5="911" B4_6="50" B4_7="1248" B4_8="131" B4_14="0" />
    <asiguratD D_1="B1114" D_2="578" D_5="01.12.2010" D_6="01.12.2010" D_7="11.12.2010" D_9="01" D_10="2" D_14="5" D_15="5" D_16="10" D_17="15685" D_18="131" D_19="119.7328" D_20="449" D_21="449" />

  </asigurat>
  <asigurat idAsig="2" cnpAsig="1790228297307" numeAsig="ADET" prenAsig="FLORIN" dataAng="01.01.2011" casaSn="_B" asigCI="1" asigSO="1">   


  </asigurat>  
</declaratieUnica>

I'm applying this xsl, but does not works:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="*">
    <xsl:for-each select="*/declaratieUnica/asigurat">
      <xsl:sort select="name()" />   
    </xsl:for-each>
    <xsl:copy-of select="./."/>
  </xsl:template>
</xsl:stylesheet>

Update from comments

In "asigurat" the elements are sorted: asiguratD, coAsigurati are at the end...

2
  • Obs.: In "asigurat" the elements are sorted: asiguratD, coAsigurati are at the end... Commented Feb 11, 2011 at 15:01
  • Neither example shows the XSL linking, I just want to be Captain Obvious and rule out the possibility that you forgot to add the stylesheet to your XML file. Commented Feb 11, 2011 at 15:06

1 Answer 1

5

Does the following do what you want?

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

  <xsl:output indent="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[*]">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="*">
        <xsl:sort select="local-name()"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

[edit] If you want to exclude a child of a certain element from sorting you could use e.g.

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:v1="mfp:anaf:dgti:declaratie_unica:declaratie:v1"
  version="1.0">

  <xsl:output indent="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[*]">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="*">
        <xsl:sort select="local-name()"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="v1:asigurat" priority="3">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="v1:coAsigurati"/>
      <xsl:apply-templates select="*[not(self::v1:coAsigurati)]">
        <xsl:sort select="local-name()"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

3 Comments

But how toput only coAsigurati in the first position (escape him from sorting) ? This is a hard one question :)
But how toput only coAsigurati in the first position (escape him from sorting) ? This is a hard one question :)
@Martin Honnen: +1 Correct answer. But local-name() instead of name() (from the original question) might confuse people making think this is the key change and not the empty iteration (and pattern and xsl:copy-of/@select, etc.). Also *[*] it's not the request: In "asigurat" the elements are sorted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.