Domanda

I am working on XML transformation using XSLT and facing issue while renaming tag. Please find below detail for the same. My transformed XML should have BookName instead of Name and LibraryName instead of Name tag.

Input XML

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Catalog xmlns="http://example.com">
    <Books>
        <Book>
            <Name>Wise Otherwise</Name>
            <author>Great Expectations</author>
        </Book>
        <Book>
            <Name>Rich Dad Poor Dad</Name>
            <author>Orange</author>
        </Book>
    </Books>
    <libraries>
        <library>
            <Name> Forsyth </Name>
            <city> Cumming </city>
        </library>
        <library>
            <Name> COBB </Name>
            <city> Marietta </city>
        </library>
    </libraries>
</Catalog>

Expected XML After Transformation

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Catalog xmlns="http://example.com">
    <Books>
        <Book>
            <BookName>Wise Otherwise</BookName>
            <author>Great Expectations</author>
        </Book>
        <Book>
            <Name>Rich Dad Poor Dad</Name>
            <author>Orange</author>
        </Book>
    </Books>
    <libraries>
        <library>
            <LibraryName> Forsyth </LibraryName>
            <city> Cumming </city>
        </library>
        <library>
            <LibraryName> COBB </LibraryName>
            <city> Marietta </city>
        </library>
    </libraries>
</Catalog>

My XSLT for the same

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://example.com">
<xsl:output method="xml" indent="yes"/>

<xsl:strip-space  elements="*"/>

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

 <xsl:template match="ns:Name">
    <xsl:for-each select="Catalog/Books/Book/Name">
        <BookName>
            <xsl:apply-templates />
        </BookName>
    </xsl:for-each>
    <xsl:for-each select="Catalog/libraries/library/Name">
        <LibraryName>
            <xsl:apply-templates />
        </LibraryName>
    </xsl:for-each>
</xsl:template>     
</xsl:stylesheet>
È stato utile?

Soluzione

You can use this XSLT for reference:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://example.com" xmlns="http://example.com" exclude-result-prefixes="ns">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="ns:Book/ns:Name">
        <BookName>
            <xsl:apply-templates/>
        </BookName>
    </xsl:template>

    <xsl:template match="ns:library/ns:Name">
        <LibraryName>
            <xsl:apply-templates/>
        </LibraryName>
    </xsl:template>
</xsl:stylesheet>

I declared the namespace with and without prefix. Therefore all new created elements will belong to the default namespace. Also excluded the prefixed one since it is not used.

You can write several templates for matching the nodes you want to change. For example read this tutorial: http://www.xmlplease.com/xsltidentity

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top