Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT to rename qualified root element, keep other namespaces

I am trying to write an XSLT to manipulate our XML where we need to:

  • Rename the qualified root element from 'tool:view' to 'indexes'
  • Rename 'tool:view' attribute from 'name' to 'view'
  • Change default namespace from 'http://company/server/views/index' to 'http://company/views/index'
  • Remove tool namespace Keep other namespaces (xsi, atom)

I'm having difficulties in getting the namespaces to behave correctly. I've worked through many different posts on solving this problem but none of them were exactly my scenario.

Original:

<?xml version="1.0" encoding="UTF-8"?>
<tool:view name="viewindexes" xmlns="http://company/server/views/index" xmlns:tool="http://company" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <index>
        <index>ABC</index>
        <description>ABC Description</description>
        <atom:link rel="self" href="http://server/admin/views/index/ABC?$format=xml"/>
    </index>
    <index>
        <index>DEF</index>
        <description>DEF Description</description>
        <atom:link rel="self" href="http://server/admin/views/index/DEF?$format=xml"/>
    </index>
    <atom:link rel="self" href="http://server/admin/views/index/DEF?$format=xml&amp;$count=2"/>
    <atom:link rel="next" title="Next interval" href="?$format=xml&amp;$count=2&amp;$start_index=2"/>
</tool:view>

Expected:

<?xml version="1.0" encoding="UTF-8"?>
<indexes view="viewindexes" xmlns="http://company/views/index" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <index>
        <index>ABC</index>
        <description>ABC Description</description>
        <atom:link rel="self" href="http://server/admin/views/index/ABC?$format=xml"/>
    </index>
    <index>
        <index>DEF</index>
        <description>DEF Description</description>
        <atom:link rel="self" href="http://server/admin/views/index/DEF?$format=xml"/>
    </index>
    <atom:link rel="self" href="http://server/admin/views/index/DEF?$format=xml&amp;$count=2"/>
    <atom:link rel="next" title="Next interval" href="?$format=xml&amp;$count=2&amp;$start_index=2"/>
</indexes>

XSLT:

 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:variable name="root" select="'indexes'" /> 
        <xsl:variable name="ns" select="'http://company/views/index'" /> 

        <xsl:template match="/*:view">
            <xsl:element name="{$root}" namespace="{$ns}">
                <xsl:attribute name="view">
                    <xsl:value-of select="@name"/>
                </xsl:attribute>
                <xsl:apply-templates />
            </xsl:element>
        </xsl:template>

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

Result:

<?xml version="1.0" encoding="UTF-8"?>
<indexes xmlns="http://company/views/index" view="viewindexes">
        <index xmlns="http://company/server/views/index" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:tool="http://company" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <index>ABC</index>
            <description>ABC Description</description>
            <atom:link href="http://server/admin/views/index/ABC?$format=xml" rel="self"/>
        </index>
        <index xmlns="http://company/server/views/index" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:tool="http://company" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <index>DEF</index>
            <description>DEF Description</description>
            <atom:link href="http://server/admin/views/index/DEF?$format=xml" rel="self"/>
        </index>
        <atom:link xmlns="http://company/server/views/index" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:tool="http://company" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" href="http://server/admin/views/index/DEF?$format=xml&amp;$count=2" rel="self"/>
        <atom:link xmlns="http://company/server/views/index" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:tool="http://company" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" href="?$format=xml&amp;$count=2&amp;$start_index=2" rel="next" title="Next interval"/>
    </indexes>
like image 491
Jason Morse Avatar asked Feb 13 '15 20:02

Jason Morse


1 Answers

Assuming XSLT 2.0 I would suggest to use

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://company/views/index"
  xmlns:tool="http://company"
  xmlns:svi="http://company/server/views/index"
  exclude-result-prefixes="tool svi"
>

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

        <xsl:template match="/tool:view">
            <indexes view="{@name}">
                <xsl:copy-of select="namespace::*[not(. = ('http://company', 'http://company/server/views/index'))]"/>
                <xsl:apply-templates />
            </indexes>
        </xsl:template>

        <xsl:template match="svi:*">
          <xsl:element name="{local-name()}">
                <xsl:apply-templates select="@*|node()" />
          </xsl:element>
        </xsl:template>

</xsl:stylesheet>
like image 160
Martin Honnen Avatar answered Sep 20 '22 15:09

Martin Honnen