Append new xml node under existing xml nodes using xslt - xslt

I am trying to append a new XML node under existing XML node but i wasn't able to achieve the desired result.
Please find my below XML,
<Root>
<Row>
<A1>0</A1>
<A2>1</A2>
<Preferred_First_Name>aaaa</Preferred_First_Name>
<Preferred_Last_Name>yyyy</Preferred_Last_Name>
<location>xxxx</location>
<ID>12345</ID>
</Row>
</Root>
I want to modify the above XML in such a way that Preferred_First_Name, Preferred_Last_Name and location node need to be under a new XML tag "Data".
The desired output should be like below,
<Root>
<Row>
<A1>0</A1>
<A2>1</A2>
<Data>
<Preferred_First_Name>aaaa</Preferred_First_Name>
<Preferred_Last_Name>yyyy</Preferred_Last_Name>
<location Descriptor="xxxx">
<ID type="ID">xxxx</ID>
<ID type="LocationID">xxxx</ID>
</location>
</Data>
<ID>12345</ID>
</Row>
</Root>
Can someone please help?

you can use below
<?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet xmlns:xalan="http://xml.apache.org/xalan" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="Root">
<xsl:element name="Root">
<xsl:call-template name="Row" />
</xsl:element>
</xsl:template>
<xsl:template name="Row">
<xsl:element name="Row">
<xsl:copy-of select="Row/A1"/>
<xsl:copy-of select="Row/A2"/>
<xsl:element name="Data">
<xsl:copy-of select="Row/Preferred_First_Name"/>
<xsl:copy-of select="Row/Preferred_Last_Name"/>
<xsl:element name="location">
<xsl:attribute name="Descriptor">
<xsl:value-of select="Row/location"/>
</xsl:attribute>
<xsl:element name="ID">
<xsl:attribute name="type">
<xsl:value-of select="'ID'"/>
</xsl:attribute>
<xsl:value-of select="Row/location"/>
</xsl:element>
<xsl:element name="ID">
<xsl:attribute name="type">
<xsl:value-of select="'LocationID'"/>
</xsl:attribute>
<xsl:value-of select="Row/location"/>
</xsl:element>
</xsl:element>
<xsl:copy-of select="Row/ID"/>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Please let me know this helps you

If it is okay to put <ID> after <Data> mentioned by Tim C, then the optimized solution can be:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Row">
<Row>
<xsl:apply-templates select="child::node()[not(self::Preferred_First_Name or self::Preferred_Last_Name
or self::location)]" />
<Data>
<xsl:apply-templates select="child::node()[self::Preferred_First_Name or self::Preferred_Last_Name
or self::location]"/>
</Data>
</Row>
</xsl:template>
</xsl:stylesheet>

Related

XSLT element selection based on Choose not working

I have the following XML:
<Document>
<Row>
<KEY>NIKE|JB|APPAREL|MENS</KEY>
<Period>Nov-21</Period>
</Row>
<Row>
<KEY>FASCINATE|JB|ACCESSORIES|LADIES</KEY>
<Matches>
<Row>
<KEY>FASCINATE|JB|ACCESSORIES|LADIES</KEY>
<Period>Nov-22</Period>
</Row>
</Matches>
</Row>
</Document>
I want to use XSLT to return the nested /Matches/Row/Period when the Document/Row/Period is undefined (as it is in the second Row of the XML)
So I have the following XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://exampleincludednamespace.com/"
exclude-result-prefixes="ns">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:template match="/">
<Document>
<xsl:for-each select="/Document/Row">
<xsl:variable name="period" select="/Period" />
<xsl:choose>
<xsl:when test="$period = null">
<xsl:copy>
<xsl:copy-of select="KEY | /Matches/Row/Period" />
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="KEY | Period" />
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</Document>
</xsl:template>
</xsl:stylesheet>
But it returns the following output:
<Document>
<Row>
<KEY>NIKE|JB|APPAREL|MENS</KEY>
<Period>Nov-21</Period>
</Row>
<Row>
<KEY>FASCINATE|JB|ACCESSORIES|LADIES</KEY>
</Row>
</Document>
(Note how it is not returning the nested /Matches/Row/Period in the second /Row.
I expect to get the following output:
<Document>
<Row>
<KEY>NIKE|JB|APPAREL|MENS</KEY>
<Period>Nov-21</Period>
</Row>
<Row>
<KEY>FASCINATE|JB|ACCESSORIES|LADIES</KEY>
<Period>Nov-22</Period>
</Row>
</Document>
What am I doing wrong?
undefined or null are not checked in XSLT/XPath using expression = null, you would rather use (for node-sets) <xsl:when test="expression"> e.g. <xsl:when test="Period"> that there is at least one Period child element for the context node or test="not(Period)" to check there is no Period child.
In the end I would suggest to use template matching based on the identity transformation template and put any conditions into match pattern (predicates), but that is a different issue.
Got it working with this XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://exampleincludednamespace.com/"
exclude-result-prefixes="ns">
<xsl:output method="xml" omit-xml-declaration="yes" />
<xsl:template match="/">
<Document>
<xsl:for-each select="/Document/Row">
<xsl:choose>
<xsl:when test="not(Period)">
<xsl:copy>
<xsl:copy-of select="KEY | Matches/Row/Period" />
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:copy-of select="KEY | Period" />
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</Document>
</xsl:template>
</xsl:stylesheet>
Thanks to #MartinHonnen's guidance.
I believe it could be simply:
XSLT 1.0
<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="/Document">
<xsl:copy>
<xsl:for-each select="Row">
<xsl:copy>
<xsl:copy-of select="KEY | descendant::Period[1]" />
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Generate new group based on node value in XSLT

I am new to XSLT, and I am trying to create new group based on node value eventType so if eventType is alert, create new group event.
I am checking for last sibling
Input XML
<?xml version="1.0" encoding="UTF-8"?><Rowsets >
<Row>
<eventId>2</eventId>
<plantId>1020</plantId>
<workCenter>WC1</workCenter>
<eventType>alert</eventType>
<eventText>Downtime</eventText>
<eventDesc>WorkcenterDown</eventDesc>
</Row>
<Row>
<eventId>3</eventId>
<plantId>1021</plantId>
<workCenter>WC1</workCenter>
<eventType>alert</eventType>
<eventText>Downtime</eventText>
<eventDesc>WorkcenterDown</eventDesc>
</Row>
<Row>
<eventId>4</eventId>
<plantId>1020</plantId>
<workCenter>WC2</workCenter>
<eventType>incident</eventType>
<eventText>eventtext</eventText>
<eventDesc>failed</eventDesc>
</Row>
<Row>
<plantId>1020</plantId>
<workCenter>WC2</workCenter>
<eventType>incident</eventType>
<eventText>Text</eventText>
<eventDesc>failed</eventDesc>
</Row>
</Rowsets>
Expected output:
<?xml version="1.0" encoding="UTF-8"?>
<Rowsets>
<Alert>
<element>
<Title>Downtime:DIA01</Title>
<eventDesc>WorkcenterDown</eventDesc>
</element>
<element>
<Title>Downtime:DIA01</Title>
<eventDesc>WorkcenterDown</eventDesc>
</element>
</Alert>
<Incident>
<element>
<Title>YAT < 60%:DIA01</Title>
<eventDesc>7 Parts in 60 minutes have failed</eventDesc>
</element>
<element>
<Title>YAT < 60%:DIA01</Title>
<eventDesc>7 Parts in 60 minutes have failed</eventDesc>
</element>
</Incident>
</Rowsets>
Based on eventType, I want to generate group.
I am using this 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:template match="/">
<Rowsets>
<Rowset>
<xsl:variable name="Type" select="'alert'"/>
<xsl:for-each select="/Rowsets/Rowset/Row">
<xsl:choose>
<xsl:when test="$Type = eventType">
<element>
<xsl:variable name="text" select="eventText"/>
<xsl:variable name="WC" select="workCenter"/>
<Title><xsl:value-of select="concat($text,':',$WC)" /></Title>
<xsl:copy-of select="eventDesc"/>
</element>
</xsl:when>
<xsl:otherwise>
<element>
<xsl:variable name="text" select="eventText"/>
<xsl:variable name="WC" select="workCenter"/>
<Title><xsl:value-of select="concat($text,':',$WC)" /></Title>
<xsl:copy-of select="eventDesc"/>
</element>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</Rowset>
</Rowsets>
</xsl:template>
</xsl:stylesheet>
Need help in generating id and key based on eventType
This is a grouping problem - and a rather trivial one at that. In XSLT 2.0 you could do simply:
XSLT 2.0
<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="Rowsets">
<Rowsets>
<xsl:for-each-group select="Row" group-by="eventType">
<xsl:element name="{current-grouping-key()}">
<xsl:for-each select="current-group()">
<element>
<Title>
<xsl:value-of select="eventText, workCenter" separator=":"/>
</Title>
<xsl:copy-of select="eventDesc"/>
</element>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
</Rowsets>
</xsl:template>
</xsl:stylesheet>
Alternatively, with only two possible types, you could do:
XSLT 1.0
<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="Rowsets">
<Rowsets>
<Alert>
<xsl:apply-templates select="Row[eventType='alert']"/>
</Alert>
<Incident>
<xsl:apply-templates select="Row[eventType='incident']"/>
</Incident>
</Rowsets>
</xsl:template>
<xsl:template match="Row">
<element>
<Title>
<xsl:value-of select="eventText"/>
<xsl:text>:</xsl:text>
<xsl:value-of select="workCenter"/>
</Title>
<xsl:copy-of select="eventDesc"/>
</element>
</xsl:template>
</xsl:stylesheet>
This is assuming you don't mind creating a group even if it is empty. Otherwise you would do:
<xsl:template match="Rowsets">
<Rowsets>
<xsl:variable name="alerts" select="Row[eventType='alert']"/>
<xsl:variable name="incidents" select="Row[eventType='incident']"/>
<xsl:if test="$alerts">
<Alert>
<xsl:apply-templates select="Row[eventType='alert']"/>
</Alert>
</xsl:if>
<xsl:if test="$incidents">
<Incident>
<xsl:apply-templates select="Row[eventType='incident']"/>
</Incident>
</xsl:if>
</Rowsets>
</xsl:template>
P.S. Note that XML is case-sensitive: <Alert> is not the same as <alert>.

XSLT for-each namespace

I'm using a for-each in my XSLT template.
This is my example input XML:
<products>
<data>
<label_1>some_label1</label_1>
<label_2>some_label2</label_2>
<values>
<a>a</a>
<b>b</b>
</values>
</data>
<data>
<label_1>some_label1</label_1>
<label_2>some_label2</label_2>
<values>
<c>c</c>
<d>d</d>
</values>
</data>
</products>
Now based on my template:
<?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/ns">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="data">
<data>
<xsl:variable name="values" select="values" />
<xsl:for-each select="$values">
<xsl:apply-templates select="#*|node()" />
</xsl:for-each>
</data>
</xsl:template>
</xsl:stylesheet>
I get only <values></values> and that is ok for me.
That's my output:
<products>
<data>
<a>a</a>
<b>b</b>
</data>
<data>
<c>c</c>
<d>d</d>
</data>
</products>
What i need in my output is namespace like this:
<products>
<data>
<ns:a>a</ns:a>
<ns:b>b</ns:b>
</data>
<data>
<ns:c>c</ns:c>
<ns:d>d</ns:d>
</data>
</products>
So what i understand is "each element of values is applied by template". How can I add namespace ?
You can get output similar to what you show (albeit well-formed) by using:
XSLT 1.0
<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="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="data">
<xsl:copy>
<xsl:apply-templates select="values/*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="values/*">
<xsl:element name="ns:{local-name()}" namespace="http:/example.com/ns">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Or, if you prefer:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http:/example.com/ns">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/products">
<products>
<xsl:for-each select="data">
<xsl:copy>
<xsl:for-each select="values/*">
<xsl:element name="ns:{local-name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</products>
</xsl:template>
</xsl:stylesheet>
Replace http:/example.com/ns with your own namespace URI.
Credits
This answer follows the technique used in this SO answer to a similar problem.
Solution
Add namespace information to all descendants of specific elements. Augment the stylesheet by a template matching this set of nodes:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://my.ns.uri"
>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="data">
<data>
<xsl:variable name="values" select="values" />
<xsl:for-each select="$values">
<xsl:apply-templates select="#*|node()" />
</xsl:for-each>
</data>
</xsl:template>
<!--
Added template.
-->
<xsl:template match="data//*">
<xsl:element name="ns:{name()}" namespace="http://my.ns.uri">
<xsl:for-each select=".">
<xsl:apply-templates select="#*|node()" />
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

Using apply-template instead of call-template

Is it possible to replace the call-template statement in the following stylesheet with a apply-statement? So that the structure of the templates are nearly the same. With structure I mean that I have a xpath to select a element form the source xml e.g. /shiporder/address/city and I have a target xpath for my output xml e.g. /root/Address/Country then I step reverse through the source path. All /shiporder/address/city goes under Country all /shiporder/address goes under Address and the root shiporder become the tag root.
Source XML:
<shiporder>
<shipto>orderperson1</shipto>
<shipfrom>orderperson2</shipfrom>
<address>
<city>London</city>
</address>
<address>
<city>Berlin</city>
</address>
</shiporder>
Stylesheet:
<xsl:template match="/">
<xsl:apply-templates select="shiporder"/>
</xsl:template>
<xsl:template match="/shiporder">
<root>
<xsl:apply-templates select="address/city"/>
<xsl:call-template name="Identity" />
</root>
</xsl:template>
<xsl:template name="Identity">
<Identity>
<xsl:call-template name="Name" />
</Identity>
</xsl:template>
<xsl:template name="Name">
<Name>
<xsl:apply-templates select="/shiporder/shipto"/>
</Name>
</xsl:template>
<xsl:template match="/shiporder/shipto">
<Last>
<xsl:apply-templates select="text()"/>
</Last>
</xsl:template>
<xsl:template match="/shiporder/address/city">
<Country>
<xsl:apply-templates select="text()"/>
</Country>
</xsl:template>
you can use the following:
<?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" indent="yes" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/shiporder">
<root>
<xsl:apply-templates select="address/city"/>
<xsl:apply-templates select="shipto"/>
</root>
</xsl:template>
<xsl:template match="shipto">
<Identity>
<Name>
<Last><xsl:value-of select="."/></Last>
</Name>
</Identity>
</xsl:template>
<xsl:template match="/shiporder/address/city">
<Country>
<xsl:value-of select="."/>
</Country>
</xsl:template>
</xsl:stylesheet>
Generally speaking, <xsl:call-template name="..."/> can be turned into a <xsl:apply-templates select="current()" mode="..."/> and <xsl:template match="node()" mode="..."/> (as long as this mode is not used anywhere else).
But there, the upvoted answer is way more suited.

How to insert an element into a previously created element in xslt?

I have several records from the DB for a corresponding record in a file.
Example
Record no. XML
<XML_FILE_HEADER file_name="sample.txt" />
<XML_RECORD record_number="1" name="John Doe" Age="21"/>
<XML_RECORD record_number="2" name""Jessica Sanchez" Age="23"/>
<XML_FILE_FOOTER total_records="2"/>
Now for each record I have an xslt template that would create the output file in xml.
For record no 1:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt">
<xsl:output method="xml"/>
<xsl:template match="XML_FILE_HEADER">
<xsl:element name="File">
<xsl:attribute name="FileName"><xsl:value-of select="#file_name"/></xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
For records 2 and 3:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="XML_RECORD">
<xsl:element name="Record">
<xsl:attribute name="Name"><xsl:value-of select="#name"/></xsl:attribute>
<xsl:element name="Details">
<xsl:attribute name="Age"><xsl:value-of select="#Age"/></xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
For record 4:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="XML_FILE_FOOTER">
<xsl:element name="Totals">
<xsl:attribute name="Total Records"><xsl:value-of select="#total_records"/></xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
The problem with is is I would have an output of this after appending each record using the templates above:
<?xml version="1.0" encoding="UTF-8"?>
<File FileName="sample.txt"></File>
<Record Name="John Doe" Age="21"></Record>
<Record Name="Jessica Sanchez" Age="22"></Record>
<Totals Total Records="2"></Totals>
How would I be able to insert the Record and Totals elements under File? so that it would have an output like this:
<?xml version="1.0" encoding="UTF-8"?>
<File FileName="sample.txt">
<Record Name="John Doe" Age="21"></Record>
<Record Name="Jessica Sanchez" Age="22"></Record>
<Totals Total Records="2"></Totals>
</File>
Any help would be very much appreciated. Thanks.
As short and easy as this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:apply-templates select="XML_FILE_HEADER"/>
</xsl:template>
<xsl:template match="XML_FILE_HEADER">
<File FileName="{#file_name}">
<xsl:apply-templates select="../*[not(self::XML_FILE_HEADER)]"/>
</File>
</xsl:template>
<xsl:template match="XML_RECORD">
<Record name="{#name}" Age="{#Age}"/>
</xsl:template>
<xsl:template match="XML_FILE_FOOTER">
<Totals TotalRecords="{#total_records}"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML (corrected to be well-formed) document:
<t>
<XML_FILE_HEADER file_name="sample.txt" />
<XML_RECORD record_number="1" name="John Doe" Age="21"/>
<XML_RECORD record_number="2" name="Jessica Sanchez" Age="23"/>
<XML_FILE_FOOTER total_records="2"/>
</t>
the wanted, correct result is produced:
<File FileName="sample.txt">
<Record name="John Doe" Age="21"/>
<Record name="Jessica Sanchez" Age="23"/>
<Totals TotalRecords="2"/>
</File>
Explanation:
Proper use of templates.
Proper use of xsl:apply-templates for ordering the results.
Proper use of AVT (Attribute Value Templates).
Avoided the use of xsl:element
No use of xsl:call-template.
Implemented in "push style" almost completely.
What you want is the <xsl:call-template name="templatename" /> element. This allows you to call a template from inside another template.
Something like
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt">
    <xsl:output method="xml"/>
<xsl:template match="/XML_FILE/XML_FILE_HEADER">
<xsl:element name="File">
<xsl:attribute name="FileName">
<xsl:value-of select="#file_name"/>
</xsl:attribute>
<xsl:for-each select="/XML_FILE/XML_RECORD">
<xsl:call-template name="RecordTemplate" />
</xsl:for-each>
<xsl:call-template name="TotalTemplate" />
</xsl:element>
</xsl:template>
<xsl:template name="RecordTemplate">
<xsl:element name="Record">
<xsl:attribute name="Name"><xsl:value-of select="#name"/></xsl:attribute>
<xsl:attribute name="Age"><xsl:value-of select="#Age"/></xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template match="/XML_FILE/XML_FILE_FOOTER" name="TotalTemplate">
<xsl:element name="Totals">
<xsl:attribute name="Total Records"><xsl:value-of select="#total_records"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
of course your input you have to be XML valid (i.e. have a single root node) like so
<XML_FILE>
<XML_FILE_HEADER file_name="sample.txt" />
<XML_RECORD record_number="1" name="John Doe" Age="21"/>
<XML_RECORD record_number="2" name""Jessica Sanchez" Age="23"/>
<XML_FILE_FOOTER total_records="2"/>
</XML_FILE>