Re-arrange xml elements (with Namespaces) using XSLT

ramu_src2k
ramu_src2k used Ask the Experts™
on
I need to rearrange the below XML along with the namespaces. In my earlier post (http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/XSLT/Q_25089800.html) i was able to rearrange the xml without namespaces . Can any one help in this regard.

Thanks in Advance

Input XML:

<?xml version="1.0" encoding="UTF-16"?>
<sport:codes xmlns:sport="icc:ft">
<sport:Entity sport:name="Cricket" >
<somedata11 xmlns="abc">Raghu</somedata11>
<somedata22 xmlns="abc">Hemanth</somedata22>
</sport:Entity>
<sport:Entity sport:name="Golf">
                <somedata11

xmlns:test="xxx"><test:data21>Shilpa</test:data21></somedata11>
                <somedata22

xmlns:test="xxx"><test:data22>Sudha</test:data22></somedata22>
</sport:Entity>
<sport:Entity sport:name="Football">
<somedata11 xmlns:t1="t1ns" xmlns:t2="t2ns">Ramesh</somedata11>
<somedata22 xmlns:t1="t1ns" xmlns:t2="t2ns">Sivakumar</somedata22>
</sport:Entity>
<sport:Entity sport:name="Tennis">
                <somedata11>John</somedata11>
                <somedata22>Peter</somedata22>
</sport:Entity>
</sport:codes>

XSLT used:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sport="icc:ft" version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes" encoding="UTF-16"/>
<xsl:template match="sport:codes">
<sport:codes  xmlns:sport="icc:ft">
<xsl:for-each select="sport:Entity">
<xsl:sort
select="(number(@sport:entityname='Football') * 1)
    + (number(@sport:entityname='Tennis') * 2)
    + (number(@sport:entityname='Golf') * 3)
    + (number(@sport:entityname='Cricket') * 4)"
 order="ascending" data-type="number" />
<xsl:copy-of select="."/>
</xsl:for-each>
</sport:codes>
    </xsl:template>
</xsl:stylesheet>

Expected Output XML:

<?xml version="1.0" encoding="UTF-16"?>
<sport:codes xmlns:sport="icc:ft">
<sport:Entity sport:name="Football">
<somedata11 xmlns:t1="t1ns" xmlns:t2="t2ns">Ramesh</somedata11>
<somedata22 xmlns:t1="t1ns" xmlns:t2="t2ns">Sivakumar</somedata22>
</sport:Entity>
<sport:Entity sport:name="Tennis">
                <somedata11>John</somedata11>
                <somedata22>Peter</somedata22>
</sport:Entity>
<sport:Entity sport:name="Golf">
                <somedata11

xmlns:test="xxx"><test:data21>Shilpa</test:data21></somedata11>
                <somedata22

xmlns:test="xxx"><test:data22>Sudha</test:data22></somedata22>
</sport:Entity>
<sport:Entity sport:name="Cricket" >
<somedata11 xmlns="abc">Raghu</somedata11>
<somedata22 xmlns="abc">Hemanth</somedata22>
</sport:Entity>
</sport:codes>
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Information Architect
Top Expert 2006
Commented:
There actually is a shortcut you could take
<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:sport="icc:ft" version="1.0">
    <xsl:strip-space elements="*"/> 
    <xsl:output method="xml" indent="yes" encoding="UTF-16"/> 
    <xsl:template match="sport:codes">
        <sport:codes  xmlns:sport="icc:ft">
            <xsl:for-each select="sport:Entity">
                <xsl:sort 
                    select="translate(@sport:name, 'FTGC', 'ABCD')"
                    order="ascending" data-type="text" />
                <xsl:copy-of select="."/> 
            </xsl:for-each>
        </sport:codes>
    </xsl:template>
</xsl:stylesheet>

Open in new window

Gertone (Geert Bormans)Information Architect
Top Expert 2006

Commented:
your only error was by the way that you had the attribute name wrong
                <xsl:sort 
                    select="(number(@sport:name='Football') * 1)
                    + (number(@sport:name='Tennis') * 2)
                    + (number(@sport:name='Golf') * 3)
                    + (number(@sport:name='Cricket') * 4)"
                    order="ascending" data-type="number" />

Open in new window

Gertone (Geert Bormans)Information Architect
Top Expert 2006

Commented:
note that my approach with the translate only works if the first letter of each word to sort is distinct
(otherwise you need to expand by also translating teh second letter!)

I prefer my earliest suggestion
There is a way in between by putting all names in a parameter
something like this
<xsl:param name="sortstring">#Football=1#Tennis=2#Golf=3#Cricket=4#</xsl:param>
This way I emulate the lookup table in one string, instead of a full table
you can use substring-before and substring-after to actually get the sort done

All of my alternatives give more flexible and more readable XSLT, over your sum,
but that could be a matter of taste
Gertone (Geert Bormans)Information Architect
Top Expert 2006

Commented:
weird decission this is
basically all my comments are good for a solution
you can safely accept ID:26436364
Gertone (Geert Bormans)Information Architect
Top Expert 2006

Commented:
weird decission this is
basically all my comments are good for a solution
you can safely accept ID:26436364

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial