Generating Comments, Processing Instructions, and Elements
When generating XML, it is often useful to generate comments, processing instructions, and elements that are named programmatically. XSLT provides a set of commands for creating specific kinds of nodes in the output. Just as the <xsl:attribute>
element can insert an attribute into the tree, XSLT provides a similar set of elements for inserting other types of nodes. For more information about the <xsl:attribute>
element, see Selecting and Outputting Attributes.
The <xsl:comment>
element inserts a comment into the output. Comments within the style sheet are not passed through to the output, but are treated as comments on the style sheet itself. When a comment is required in the output, place the comment text within an <xsl:comment>
element.
The <xsl:processing-instruction>
element inserts a processing instruction into the output. The name
attribute specifies the name of the attribute, and the content of the element becomes the text of the processing instruction.
The <xsl:element>
element provides an alternative mechanism for creating elements in the output. The name
attribute specifies the name of the element. The following two ways of creating a <DIV>
element produce identical results.
1) <DIV class="menuItem"> Choose me </DIV> 2) <xsl:element name="DIV"> <xsl:attribute name="class">menuItem</xsl:attribute> Choose me </xsl:element>
You must use the <xsl:attribute>
element to add attributes to elements that have been created using the <xsl:element>
element. You cannot add attributes to these elements directly.
Because XSLT allows output elements to be specified directly, there are only a few situations in which <xsl:element>
is useful. For example, you can use <xsl:element>
as an escaping mechanism for creating XSLT elements in the output, which allows a style sheet to generate other style sheets.
Example
The following example converts style sheets to use the <xsl:element>
syntax. It uses <xsl:element>
to generate elements in the XSLT namespace, and inserts processing instructions and a comment at the beginning of the file.
This style sheet has five template rules.
- The first template adds a boilerplate to the root of the output document. It also selects all comments and the document element to be copied to the output.
- The second template copies comments, processing instructions, and text nodes to the output.
- The third template converts elements to the
<xsl:element>
syntax. - The fourth template converts attributes to the
<xsl:attribute>
syntax. - The fifth template ensures that any elements from the XSLT namespace are copied to the output with their attributes, and not converted by the third template.
XSLT File (convert.xsl)
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <xsl:processing-instruction name="xml-stylesheet">type="text/xsl" href="style.xsl"</xsl:processing-instruction> <xsl:comment>Style sheet converted automatically to <xsl:element> syntax</xsl:comment> <xsl:apply-templates select="comment()"/> <xsl:apply-templates select="*"/> </xsl:template> <!-- Copy text, comments and processing instructions. --> <xsl:template match="comment() | processing-instruction() | text()"> <xsl:copy> <xsl:apply-templates /> </xsl:copy> </xsl:template> <!-- Convert non-XSLT elements to <xsl:element> syntax. --> <xsl:template match="*"> <xsl:element name="xsl:element"> <xsl:attribute name="name"><xsl:value-of select="name(.)"/></xsl:attribute> <xsl:apply-templates select="@*"/> <!-- Consolidate. --> <xsl:apply-templates select="node()"/> </xsl:element> </xsl:template> <!-- Convert non-XSLT attribute to <xsl:attribute> syntax. --> <xsl:template match="@*"> <xsl:element name="xsl:attribute"> <xsl:attribute name="name"><xsl:value-of select="name(.)"/></xsl:attribute> <xsl:value-of select="."/> </xsl:element> </xsl:template> <!-- Copy namespace attributes. --> <xsl:template match="@xmlns:*"> <xsl:copy><xsl:value-of select="."/></xsl:copy> </xsl:template> <!-- Copy XSLT elements and their attributes. --> <xsl:template match="xsl:*"> <xsl:copy> <xsl:for-each select="@*"> <xsl:copy><xsl:value-of select="."/></xsl:copy> </xsl:for-each> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
When you apply this XSLT style sheet to the following XML document,
XML File (convert.xml)
<?xml version="1.0"?> <book> <title>title</title> <author> <last-name>last name</last-name> <first-name>first name</first-name> </author> <publisher>publisher</publisher> <date>date</date> <price currency="usd">10.0</price> </book>
you get the following output from the XSLT processor.
XLST Processor Output:
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="style.xsl"?> <!-- Style sheet converted automatically to <xsl:element> syntax --> <xsl:element name="book" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:element name="title">title</xsl:element> <xsl:element name="author"> <xsl:element name="last-name">last name</xsl:element> <xsl:element name="first-name">first name</xsl:element> </xsl:element> <xsl:element name="publisher">publisher</xsl:element> <xsl:element name="date">date</xsl:element> <xsl:element name="price"> <xsl:attribute name="currency">usd</xsl:attribute> 10.0 </xsl:element> </xsl:element>