0
votes

My input xml is

<?xml version="1.0" encoding="UTF-8"?>
<foobar atr0="NO" atr2="NO">
    <foo atr1="NO" more="more">ONE</foo>
    <bar atr6="ATR">
        <baz attr="123" attr222="22">TWO</baz>
    </bar>
</foobar>

My desired output is

<?xml version="1.0" encoding="UTF-8"?>
<foobar>
    <foo>
        <a>
            <a>
                <a>atr1</a>
                <v>NO</v>
            </a>
            <a>
                <a>more</a>
                <v>more</v>
            </a>
        </a>
        <v>ONE</v>
    </foo>
    <bar>
        <baz>
            <a>
                <a>
                    <a>attr</a>
                    <v>123</v>
                </a>
                <a>
                    <a>attr222</a>
                    <v>22</v>
                </a>
            </a>
            <v>TWO</v>
        </baz>
        <a>
            <a>
                <a>atr6</a>
                <v>ATR</v>
            </a>
        </a>
    </bar>
    <a>
        <a>
            <a>atr0</a>
            <v>NO</v>
        </a>
        <a>
            <a>atr2</a>
            <v>NO</v>
        </a>
    </a>
</foobar>

I am trying to break each attribute to separate distinctive elements with name and value .the foobar element attributes are the last child of the foobar element children. A parent element will have its attributes as the last children.

my xslt script is -

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@*| node()"/>
            <v>
                <xsl:value-of select="."/>
            </v>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*">
        <a>
            <a>
                <xsl:value-of select="name()"/>
            </a>
            <v>
                <xsl:value-of select="."/>
            </v>
        </a>
    </xsl:template>
</xsl:stylesheet>

this is good for 1 attribute. What can i do for nested elements and attributes?

1

1 Answers

0
votes

The following XSLT:

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

    <!-- Matches all kind of nodes -->
    <xsl:template match="*">
        <xsl:copy>
            <xsl:apply-templates select="*" />
            <a>
                <xsl:apply-templates select="@*" />
            </a>
            <xsl:apply-templates select="text()" />
        </xsl:copy>
    </xsl:template>

    <!-- Matches all attributes -->
    <xsl:template match="@*">
        <a>
            <a><xsl:value-of select="name()" /></a>
            <v><xsl:value-of select="." /></v>
        </a>
    </xsl:template>

    <!-- Matches text nodes -->
    <xsl:template match="text()">
        <v><xsl:value-of select="." /></v>
    </xsl:template>
</xsl:stylesheet>

Produces the wanted output.