From child elements to attributes

Still working on XSLT with Saxon, here we'll have a look at the xsl:copy element that copies just a bare node from the input xml to the resulting file, without considering descendant node or attribute, if any.

An usage for such a stripped down copy is showed here, where we want to transform an xml swapping the child nodes as attributes. This is the input:

<?xml version="1.0" encoding="UTF-8"?>
<People>
<Person>
<FirstName>Tom</FirstName>
<LastName>Smith</LastName>
</Person>
<Person>
<FirstName>Bill</FirstName>
<LastName>Krill</LastName>
</Person>
<Person>
<FirstName>Phil</FirstName>
<LastName>Delphi</LastName>
</Person>
</People>

We want to get this as output:

<?xml version="1.0" encoding="UTF-8"?>
<People>
<Person FirstName="Tom" LastName="Smith"/>
<Person FirstName="Bill" LastName="Krill"/>
<Person FirstName="Phil" LastName="Delphi"/>
</People>

Here is the XSLT we use:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

<xsl:template match="/">
<People>
<xsl:apply-templates select="/People/Person"/> <!-- 1 -->
</People>
</xsl:template>

<xsl:template match="Person"> <!-- 2 -->
<xsl:copy> <!-- 3 -->
<xsl:attribute name="FirstName"> <!-- 4 -->
<xsl:value-of select="FirstName"/> <!-- 5 -->
</xsl:attribute>
<xsl:attribute name="LastName">
<xsl:value-of select="LastName"/>
</xsl:attribute>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

1. we use apply-templates on each person
2. here is the called template relative to (1)
3. copy the current element (a Person, actually)
4. generate a FirstName attribute in the copied (stripped down) node
5. set as value-of the output FirstName attribute the value of the input FirstName child
And then the same for a second attribute.

And here how I called Saxon:
java -jar c:\dev\saxon\saxon9he.jar in.xml change.xslt -o:out.xml

More information on XSLT and Saxon in chapter eight of Beginning XML by David Hunter et al. (Wrox).

No comments:

Post a Comment