Generating Comments, Processing Instructions, and Elements

MSXML 5.0 SDK

Microsoft XML Core Services (MSXML) 5.0 for Microsoft Office - XSLT Developer's Guide

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.

  1. 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.
  2. The second template copies comments, processing instructions, and text nodes to the output.
  3. The third template converts elements to the <xsl:element> syntax.
  4. The fourth template converts attributes to the <xsl:attribute> syntax.
  5. 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 
&lt;xsl:element&gt; 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>