user3873113
user3873113

Reputation: 27

Find node value and create new node in XML using XSLT

I want to modify existing XML file using XSLT. The original XML file is

<?xml version="1.0" encoding="UTF-8"?>
<entry>
    <object>
        <items>
            <item>
                <name>John Doe</name>    <!-- Changed tag to closing tag -->
                <public-url>http://www.johndoe.com</public-url>
            </item>
        </items>
        <records>
            <record>
                <person>
                    <field name="book">
                        <text>A book</text>
                        <links>
                            <link>http://www.acook.com</link>
                        </links>
                    </field>
                </person>
            </record>
        </records>
    </object>
</entry>

Now I want to use XSL to get the the user info from <item> and insert a new <field> node into <person>. The final result will look like this.

<?xml version="1.0" encoding="UTF-8"?>
<entry>
    <object>
        <items>
            <item>
                <name>John Doe<name>
                <public-url>http://www.johndoe.com</public-url>
            </item>
        </items>
        <records>
            <record>
                <person>
                    <field name="author">
                        <text>John Doe</text>
                        <links>
                            <link>http://www.johndoe.com</link>
                        </links>
                    </field>
                    <field name="book">
                        <text>A book</text>
                        <links>
                            <link>http://www.acook.com</link>
                        </links>
                    </field>
                </person>
            </record>
        </records>
    </object>
</entry>

Below is my attempt, I want to get the <name> and <public-url> value from the <item> and become two variables. Create a new <field> using these two variables and insert into <record>. Currently I can't figure out a way to insert this new node into the correct location.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.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()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="item/">
    <xsl:variable name="username" select="@name" />
    <xsl:variable name="userurl" select="@public-url" />
    <xsl:copy-of select="."/>
    <field name="author">
    <text><xsl:value-of select="$username"/></text>
    <links>
         <link>
             <xsl:value-of select="$userurl" />
         </link>
    </links>
    </field>
</xsl:template>
</xsl:stylesheet>

Please advices, Thank you!

Upvotes: 0

Views: 1282

Answers (1)

kalinma
kalinma

Reputation: 527

This should do it.

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

<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="person">
    <xsl:element name="person">
        <xsl:element name="field">
            <xsl:attribute name="name">
                <xsl:text>author</xsl:text>
            </xsl:attribute>
            <xsl:element name="text">
                <xsl:value-of select="./ancestor::object/items/item/name"/>
            </xsl:element>
            <xsl:element name="links">
                <xsl:element name="link">
                    <xsl:value-of select="./ancestor::object/items/item/public-url"/>
                </xsl:element>
            </xsl:element>
        </xsl:element>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

Upvotes: 1

Related Questions