Use literal result elements, literal text, and instruction elements in an XSLT stylesheet.
This is a hack for XSLT beginners. If you are adding or changing markup in a result tree with XSLT, this hack will help you do it. You will learn how to use literal result elements (along with literal text) and XSLT instruction elements to build your output with new or additional markup.
A literal result element in XSLT is an XML element written literally in a template. Literal result elements can include attributes and must produce well-formed output. Literal text appears as plain, literal text in templates, for stylesheets that have text output.
The stylesheet timedate.xsl, shown in Example 3-35, augments time.xml with additional markup using literal result elements.
Example 3-35. timedate.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="ISO-8859-1" indent="yes"/> <xsl:template match="/"> <instant> <xsl:apply-templates select="time"/> <date> <year>2004</year> <month>-06</month> <day>-30</day> </date> </instant> </xsl:template> <xsl:template match="time"> <xsl:copy> <xsl:attribute name="timezone"> <xsl:value-of select="@timezone"/> </xsl:attribute> <xsl:copy-of select="hour|minute|second|atomic"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
On line 2, the output is encoded as Latin1 or ISO-8859-1 (http://en.wikipedia.org/wiki/ISO_8859-1). The
template starting on line 4 uses the literal result element
instant
(see lines 5 and 12) to wrap a new
document element around the output. Lines 7 through 11 add new markup
as well—the date
element with children
year
, month
, and
day
.
Apply timedate.xsl to
time.xml with Xalan C++ or another XSLT
processor of your choice. I like Xalan C++ (http://xml.apache.org/xalan-c/) because
it’s fast and, among other things, allows
fine-grained control over indentation with the -i
option (follow -i
with the number of spaces you
want to indent at each level of depth in the structure):
xalan -i 2 time.xml timedate.xsl
You will see this output with new markup highlighted in bold (Example 3-36).
Example 3-36. Output of timedate.xsl
<?xml version="1.0" encoding="ISO-8859-1"?> <instant> <time timezone="PST"> <hour>11</hour> <minute>59</minute> <second>59</second> <atomic signal="true"/> </time> <date> <year>2004</year> <month>-06</month> <day>-30</day> </date> </instant>
timetext.xsl in Example 3-37 uses literal text in its template, shown in bold:
Example 3-37. timetext.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="time">Time:
<xsl:value-of select="hour"/>:<
xsl:value-of select="minute"/
>:<xsl:value-of select="second"/><xsl:text> </xsl:text>
<xsl:value-of select="meridiem"/>
</xsl:template>
</xsl:stylesheet>
The literal text Time
: and the two colons
(:) will appear in the output along with the other
computed values. Apply the stylesheet:
xalan time.xml timetext.xsl
Here is the result:
Time: 11:59:59 p.m.
The text
element is an example of an XSLT
instruction element. In timetext.xsl, the
text
element inserts a single space in the output.
A discussion on instruction elements follows.
We’ll discuss the XSLT instruction elements shown in Table 3-1 in this section.
Table 3-1. XSLT instruction elements
The stylesheet instruct.xsl , shown in Example 3-38, uses all these instruction elements.
Example 3-38. instruct.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="UTF-8" indent="yes"/> <xsl:attribute-set name="att"> <xsl:attribute name="signal"> <xsl:value-of select="/time/atomic/@signal"/> </xsl:attribute> <xsl:attribute name="location">Ft. Collins</xsl:attribute> </xsl:attribute-set> <xsl:template match="time"> <xsl:processing-instruction name="xml-stylesheet"> href="time.xsl" type="text/xsl" </xsl:processing-instruction> <xsl:comment> a time instant </xsl:comment> <xsl:element name="{name( )}" namespace="urn:wyeast-net:xslt"> <xsl:attribute name="timezone"> <xsl:value-of select="@timezone"/> </xsl:attribute> <xsl:element name="hour" xmlns="urn:wyeast-net:xslt"> <xsl:value-of select="hour"/> </xsl:element> <xsl:element name="minute" xmlns="urn:wyeast-net:xslt"> <xsl:value-of select="minute"/> </xsl:element> <xsl:element name="second" xmlns="urn:wyeast-net:xslt"> <xsl:value-of select="second"/> </xsl:element> <xsl:element name="meridiem" xmlns="urn:wyeast-net:xslt"> <xsl:value-of select="meridiem"/> </xsl:element> <xsl:element name="atomic" xmlns="urn:wyeast-net:xslt" use-attribute-sets="att"/> </xsl:element> </xsl:template> </xsl:stylesheet>
Early on, this stylesheet generates an XML stylesheet processing
instruction (line 11) and a comment (line 13). The document element
for the result tree is generated based on the name of the matched
time
element ({name( )}
in the
name
attribute is an attribute value template). An
attribute, timezone
, is created (line 16) with its
value derived from time
’s
timezone
attribute.
The namespace
attribute states that the new
time
element will be in a default namespace named
with a URN (http://www.ietf.org/rfc/rfc2141.txt),
urn:wyeast-net:xslt
. Child elements will also be
in this namespace (see lines 19-31). Each of these child elements
derives its content from corresponding elements in the source
document time.xml.
The atomic
element uses the attribute set
att
, defined on lines 3-8.
attribute-set
is a top-level element, meaning that
it must be a child of the stylesheet
element. This
attribute set has two attributes, signal
and
location
, which will be added to
atomic
in the result tree.
Apply this stylesheet using this line:
xalan -i 1 time.xml instruct.xsl
The result will look like Example 3-39.
Example 3-39. Output of result.xsl
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet href="time.xsl" type="text/xsl" ?> <!-- a time instant --> <time xmlns="urn:wyeast-net:xslt" timezone="PST"> <hour>11</hour> <minute>59</minute> <second>59</second> <meridiem>p.m.</meridiem> <atomic signal="true" location="Ft. Collins"/> </time>
18.119.105.239