I needed to use XSL to generate simple plain text output from XML. Since I didn\'t find any good, concise example online, I decided to post my solution here. Any links refer
script/command
and eliminate the xsl:for-each
concat()
can be used to shorten the expression and save you from explicitly inserting so many <xsl:text>
and <xsl:value-of>
elements.

for the carriage return, rather than relying on preserving the line-break between your <xsl:text>
element is a bit more safe, since code formatting won't mess up your line breaks. Also, for me, it reads as an explicit line-break and is easier to understand the intent.<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="script/command">
<xsl:value-of select="concat('at -f '
,username
,' '
,startTime/@hours
,':'
,startTime/@minutes
,' '
,startDate
,'
')"/>
</xsl:template>
</xsl:stylesheet>
Just for fun: this can be done in a very general and compact way:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:apply-templates select="node()|@*"/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="username">
at -f <xsl:apply-templates select="*|@*"/>
</xsl:template>
</xsl:stylesheet>
when applied on this XML document:
<script>
<command>
<username>John</username>
<startTime hours="09:" minutes="33"/>
<startDate>05/05/2011</startDate>
<username>Kate</username>
<startTime hours="09:" minutes="33"/>
<startDate>05/05/2011</startDate>
<username>Peter</username>
<startTime hours="09:" minutes="33"/>
<startDate>05/05/2011</startDate>
</command>
</script>
the wanted, correct result is produced:
at -f 09:33 05/05/2011
at -f 09:33 05/05/2011
at -f 09:33 05/05/2011
Note: This genaral approach is best applicable if all the data to be output is contained in text nodes -- not in attributes.