The xsl:output Element

The <xsl:output> Element

You first saw the <xsl:output> element in Chapter 2, and you use this element primarily to set the type of the result document. That type can determine, for example, whether the XSLT processor will write the XML processing instruction, <?xml version="1.0"?> , at the beginning of the document, and it can determine the MIME type (such as text/xml or text/html) of documents sent back from an XSLT processor on a Web server to a browser. In addition, if you set the output type to HTML, most XSLT processors recognize that not all elements in HTML need closing as well as opening tags, and so on.

The following list includes the attributes of <xsl-output> :

  • cdata-section-elements (optional). Sets the names of those elements whose content should be output as CDATA sections. Set to a whitespace-separated list of QNames.

  • doctype-public (optional). Specifies the public identifier to be used in the <!DOCTYPE> declaration in the output. Set to a string value.

  • doctype-system (optional). Specifies the system identifier to be used in the <!DOCTYPE> declaration in the output. Set to a string value.

  • encoding (optional). Sets the character encoding. Set to a string value.

  • indent (optional). Specifies whether the output should be indented to show its nesting structure. Set to yes or no.

  • media-type (optional). Sets the MIME type of the output. Set to a string value.

  • method (optional). Sets the output format. Set to xml, html, text, or a valid QName.

  • omit-xml-declaration (optional) Specifies whether the XML declaration should be included in the output. Set to yes or no.

  • standalone (optional). Specifies whether an XML standalone declaration should be included in the output and sets its value if so. Set to yes or no.

  • version (optional). Sets the version of the output. Set to a valid NMToken.

The most-used attribute of this element is method , because thats what you set to the output tree type you want. Officially, the default output method is HTML if all three of the following conditions are satisfied:

  • The root node of the result tree has an element child.

  • The name of the document element of the result tree has a local part html (in any combination of upper- and lowercase) and a null namespace URI.

  • Any text nodes before the first element child of the root node contain only whitespace characters .

If all three of these conditions are met, then the output method is set to HTML by default. Otherwise, the default output method is XML.

You shouldnt rely on default settings for method , however, but rather assign this attribute a value. The three common settings for the method attribute are html, xml, and text, and Ill take a look at them in the following sections.

Output Method: HTML

The XSLT processor is supposed to take certain actions if the output method is HTML. For example, for this output method, the version attribute indicates the version of the HTML. The default value is 4.0.

This method should not add an end-tag for empty elements. (For HTML 4.0, the empty elements are <AREA>, <BASE>, <BASEFONT>, <BR>, <COL>, <FRAME>, <HR>, <IMG>, <INPUT>, <ISINDEX>, <LINK>, <META> , and <PARAM> .) The HTML output method should recognize the names of HTML elements regardless of case.

Also, according to W3C, the HTML output method should not add escaping for the content of <SCRIPT> or <STYLE> elements. For example, the following literal result element:

 <SCRIPT>      if (x &lt; y) {...}  </SCRIPT> 

or this one, which uses a CDATA section:

 <SCRIPT>      <![CDATA[if (x < y) {...}]]>  </SCRIPT> 

should be transformed to:

 <SCRIPT>      if (x < y) {...}  </SCRIPT> 

The HTML output method should also not escape < characters that appear in attribute values.

When you set the output method to HTML, the processor may pay attention to the indent attribute. If this attribute has the value yes, then the XSLT processor can add (or remove) whitespace to indent the result, as long as it doesnt affect how a browser would display the result document. The default value is yes for the HTML output method.

As youd expect, the HTML output method should terminate processing instructions with > rather than ?>. And it should support standalone attributes, as HTML does. For example, this tag:


should be transformed to:


In addition, you can set the media-type attribute for this method; default value is text/html. The HTML method should not escape a & character that appears in an attribute value immediately followed by a curly brace . Also, the encoding attribute specifies the encoding to be used. If there is a <HEAD> element, this output method should add a <META> element right after the <HEAD> tag specifying the character encoding as follows :

 <HEAD>        <META http-equiv="Content-Type" content="text/html; charset=utf-8">      .      .      . 

You can also use the doctype-public or doctype-system attributes to output a document type declaration immediately before the first element, as youll see when we transform XML to XHTML.

Those are the rules for HTML output. Heres an example of an XML to HTML example with a little pizzazz. In this case, the stylesheet will actually write JavaScript code to show how to use XSLT to create JavaScript. In particular, well read in planets.xml and create a new HTML document that displays three buttons , each with the name of one of the three planets in planets.xml. When the user clicks a button, the page will display the corresponding planets mass.

All you need is two <xsl:for-each> elements, one to loop over all three planets and create an HTML button for each, and one to loop over the planets and create a JavaScript function for each. Ill use the planets name as the name of the corresponding JavaScript function; when that function is called, itll display the corresponding planets mass. Note that to build the required JavaScript, all you have to do is to use the <xsl:value-of> element to get the names and masses of the planets. Im also using two new XSLT elements youll see later in this chapter <xsl:element> and <xsl:attribute-set> to create a new element and give it a set of attributes:

Listing 6.1 A Transformation to JavaScript
 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="">  <xsl:output method="html"/>      <xsl:template match="/PLANETS">  <HTML>      <HEAD>          <TITLE>              The Mass Page           </TITLE>          <SCRIPT LANGUAGE='javascript'>          <xsl:for-each select="PLANET">          <xsl:text>              function </xsl:text><xsl:value-of select="NAME"/><xsl:text>()              {                 display.innerHTML = 'The mass of </xsl:text>                  <xsl:value-of select="NAME"/>                  <xsl:text> equals </xsl:text>                  <xsl:value-of select="MASS"/>                  <xsl:text> Earth masses."</xsl:text>              }          </xsl:for-each>          </SCRIPT>       </HEAD>      <BODY>          <CENTER>              <H1>The Mass Page</H1>          </CENTER>          <xsl:for-each select="PLANET">              <P/>              <xsl:element name="input" use--attribute-sets="attribs"/>          </xsl:for-each>          <P/>          <P/>          <DIV ID='display'></DIV>      </BODY>  </HTML>      </xsl:template>      <xsl:attribute-set name="attribs">      <xsl:attribute name="type">BUTTON</xsl:attribute>      <xsl:attribute name="value"><xsl:value-of select="NAME"/></xsl:attribute>      <xsl:attribute name="onclick"><xsl:value-of select="NAME"/>()</xsl:attribute>      </xsl:attribute-set>  </xsl:stylesheet> 

Heres the result, including a <SCRIPT> element for the new JavaScript:

Listing 6.2 JavaScript-Enabled Result Document
 <HTML>      <HEAD>          <TITLE>              The Mass Page          </TITLE>          <SCRIPT LANGUAGE="javascript">              function Mercury()              { display.innerHTML =                      'The mass of Mercury equals .0553 Earth masses.'              }              function Venus()              {                 display.innerHTML = 'The mass of Venus equals .815 Earth masses.'              }              function Earth()              {                 display.innerHTML = 'The mass of Earth equals 1 Earth masses.'              }          </SCRIPT>      </HEAD>      <BODY>          <CENTER>              <H1>The Mass Page</H1>          </CENTER>          <P></P>          <input type="BUTTON" value="Mercury" onclick="Mercury()">          <P></P>          <input type="BUTTON" value="Venus" onclick="Venus()">          <P></P>          <input type="BUTTON" value="Earth" onclick="Earth()">          <P></P>          <P></P>          <DIV ID="display"></DIV>      </BODY>  </HTML> 

As you can see, Ive written JavaScript using XSLT to loop over the various planets. You can see this HTML document in Figure 6.1; when the user clicks a button, the corresponding planets mass is displayed.

Figure 6.1. Transforming XML into HTML with JavaScript.

Output Method: XML

Formally, when you use the XML output method, the XSLT processor creates a well-formed XML external general parsed entity. If the root node of the result tree has a single element node child and no text node children, then the entity should also be a well- formed XML document entity.

Using the XML output method, the version attribute sets the version of XML to be used for output. Note that if the XSLT processor does not support this version of XML, it is supposed to use a version of XML that it does support. The default value is 1.0.

The encoding attribute sets the encoding to use for the result document. XSLT processors are required to support at least the values UTF-8 and UTF-16 here. For other values, if the XSLT processor does not support the specified encoding it may signal an error; if it does not signal an error it should use UTF-8 or UTF-16 instead. The XSLT processor must not use an encoding that has not been approved by the W3C (in If no encoding attribute is specified, then the XSLT processor should default to UTF-8 or UTF-16.

Handling Unknown Characters

If the result document contains a character that cannot be represented in the encoding that the XSLT processor is using for output, then the character may be output as a character reference. If thats not possible, the XSLT processor should generate an error.

As with the HTML output method, if the indent attribute is set to yes, then the XML output method may add or remove whitespace in addition to the whitespace in the result tree in order to indent the result nicely . The default value is no. Note that if the whitespace is stripped, the resulting XML documents infoset should be the same as if whitespace had never been added or removed to indent the document.

Indenting Mixed-Content Documents

Its usually not a good idea to set indent to yes with XML documents that include elements with mixed content, because that confuses the XSLT processor.

You can use the cdata-section-elements attribute to specify a whitespace-separated list of element names whose content should be treated as CDATA sections. For instance, if you set the cdata-sectionelements attribute to DATA:

 <xsl:output cdata-section-elements="DATA"/> 

then this literal result element:


would be transformed into:


In addition, the XML output method should output an XML declaration in the result document unless the omit-xml-declaration attribute has been set to yes. In general, the XML declaration that is put into the result document usually includes the XML version (which is mandatory) and encoding information (although technically, encoding information is optional in XML documents). If the standalone attribute is specified, the result document should include a standalone document declaration with the same value as the value of the standalone attribute.

If you use the doctype-system attribute, the XSLT processor should create a document type declaration just before the first element. In this case, the name following <!DOCTYPE is the name of the root element. Note that if you also use the doctype-public attribute, the XSLT processor outputs PUBLIC, followed by the public identifier and then the system identifier. If you dont use the doctype-public attribute, then it should output SYSTEM, followed by the system identifier. Theoretically, the doctype-public attribute should be ignored unless the doctype-system attribute is also specified, although thats not the way most XSLT processors seem to work. Youll see how to use both doctype-public and doctype-system in this chapter when we convert XML to XHTML.

Finally, the default value for the media-type attribute is text/xml for the XML output method.

Youve already seen many XML-to-XML transformations in this book. For example, from Chapter 4, the following transformation just copies one XML document to another. Note that the output method is set to XML:

 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="">  <xsl:output method="xml"/>    <xsl:template match="@*node()">      <xsl:copy>        <xsl:apply-templates select="@*node()"/>      </xsl:copy>    </xsl:template>  </xsl:stylesheet> 

You saw this example in the beginning of the chapter, where planets.xml was reorganized based on planet density:

 <?xml version="1.0" encoding="UTF-8"?>  <DATA>      <DENSITY>          <VALUE>.983</VALUE>          <NAME>Mercury</NAME>          <MASS>.0553</MASS>          <DAY>58.65</DAY>          <RADIUS>1516</RADIUS>      </DENSITY>      <DENSITY>          <VALUE>.943</VALUE>          <NAME>Venus</NAME>          <MASS>.815</MASS>          <DAY>116.75</DAY>          <RADIUS>3716</RADIUS>      </DENSITY>      <DENSITY>          <VALUE>1</VALUE>          <NAME>Earth</NAME>          <MASS>1</MASS>          <DAY>1</DAY>          <RADIUS>2107</RADIUS>      </DENSITY>  </DATA> 

Heres the stylesheet that creates this transformation:

Listing 6.3 Reorganizing planets.xml Based on Density
 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="">  <xsl:output method="xml" indent="yes"/>      <xsl:template match="PLANETS">          <DATA>              <xsl:apply-templates/>          </DATA>     </xsl:template>      <xsl:template match="PLANET">          <DENSITY>              <VALUE>                  <xsl:value-of select="DENSITY"/>              </VALUE>              <xsl:apply-templates/>          </DENSITY>     </xsl:template>      <xsl:template match="NAME">          <NAME>              <xsl:value-of select="."/>          </NAME>      </xsl:template>      <xsl:template match="MASS">          <MASS>          <xsl:value-of select="."/>          </MASS>      </xsl:template>      <xsl:template match="RADIUS">          <RADIUS>          <xsl:value-of select="."/>          </RADIUS>      </xsl:template>      <xsl:template match="DAY">          <DAY>          <xsl:value-of select="."/>          </DAY>      </xsl:template>      <xsl:template match="DENSITY">      </xsl:template>      <xsl:template match="DISTANCE">      </xsl:template>  </xsl:stylesheet> 

You first saw the next example in Chapter 5. In this case, I just listed the planets from planets.xml, but didnt want to have the output simply say, The first three planets are: Mercury Venus Earth, but rather, The first three planets are: Mercury, Venus, and Earth. I used <xsl:if> elements to do that:

 <?xml version="1.0"?>  <xsl:stylesheet version="1.0" xmlns::xsl="">  <xsl:output method="xml"/>  <xsl:template match="PLANETS">  <DOCUMENT>      <TITLE>          The Planets      </TITLE>      <PLANETS>          The first three planets are: <xsl:apply-templates select="PLANET"/>      </PLANETS>  </DOCUMENT>  </xsl:template>  <xsl:template match="PLANET">      <xsl:value-of select="NAME"/>      <xsl:if test="position()!=last()">, </xsl:if>      <xsl:if test="position()=last()-1">and </xsl:if>      <xsl:if test="position()=last()">.</xsl:if>  </xsl:template>  </xsl:stylesheet> 

And heres the result:

 <?xml version="1.0" encoding="UTF-8"?>  <DOCUMENT>      <TITLE>          The Planets      </TITLE>      <PLANETS>          The first three planets are: Mercury, Venus, and Earth.      </PLANETS>  </DOCUMENT> 

Although many books concentrate on XML-to-HTML transformations, its important to realize that XML-to-XML transformations are becoming more and more common, which is why Im focusing on them also.

Output Method: Text

This type of output represents pure text. In this case, the output document is simply the plain text of the document tree. That is, the XSLT processor creates the result tree by outputting the string value of every text node, without any escaping.

The default value for the media-type attribute is text/plain. The encoding attribute sets the encoding that the XSLT processor uses to convert sequences of characters to sequences of bytes. Note that if the result document contains a character that cannot be represented in the encoding that the XSLT processor is using for output, the XSLT processor should generate an error.

The following example converts planets.xml into plain text using the text output method:

Listing 6.4 A Transformation to Plain Text
 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="">      <xsl:output method="text" indent="yes"/>      <xsl:template match="PLANET">            <xsl:value-of select="NAME"/>            <xsl:text>'s mass is </xsl:text>            <xsl:value-of select="MASS"/>            <xsl:text> Earth masses. Its radius is </xsl:text>            <xsl:value-of select="RADIUS"/>            <xsl:text> miles. Its day is </xsl:text>            <xsl:value-of select="DAY"/>            <xsl:text> Earth days long.</xsl:text>      </xsl:template>  </xsl:stylesheet> 

And heres the resultjust pure text, no markup, no escaped characters, no processing instructions:

 Mercury's mass is .0553 Earth masses. Its radius is 1516 miles. Its day  is 58.65 Earth days long.  Venus's mass is .815 Earth masses. Its radius is 3716 miles. Its day  is 116.75 Earth days long.  Earth's mass is 1 Earth masses. Its radius is 2107 miles. Its day  is 1 Earth days long. 

On the other hand, the text output method is not just for creating plain text; its also used for any non-XML, non-HTML text-based format. As you saw in Chapter 2, you can use it to create Rich Text Format (RTF) documents. Rich Text Format uses embedded text-based codes to specify the format of documents, and you can place those text-based codes in documents yourself if you use the text output method.

You originally saw the following example stylesheet in Chapter 2, where it was used to translate planets.xml into RTF format, which youre better equipped to understand now. In this case, Im converting planets.xml to planets.rtf by using RTF codes as literal result elements:

 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="">      <xsl:output method="text"/>      <xsl:strip-space elements="*"/>  <xsl:template match="/PLANETS">{\rtf1\ansi\deff0{\fonttbl  {\f0\fnil\fcharset0 Courier New;}}  \viewkind4\uc1\pard\lang1033\b\f0\fs36 The Planets Table\par  \b0\fs20  Name\tab Mass\tab Rad.\tab Day\par  <xsl:apply-templates/>  \par  }</xsl:template>  <xsl:template match="PLANET">  <xsl:value-of select="NAME"/>  \tab  <xsl:value-of select="MASS"/>  \tab  <xsl:value-of select="RADIUS"/>  \tab  <xsl:value-of select="DAY"/>  \tab  \par  </xsl:template>  </xsl:stylesheet> 

You can see the resulting RTF document, planets.rtf, in Figure 6.2 in Microsoft Word 2000.

Figure 6.2. Planets.rtf in Microsoft Word.

Note that the output method here is text, not something like rtf :

 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="">      <xsl:output method="text"/>  <xsl:template match="/PLANETS">{\rtf1\ansi\deff0  {\fonttbl{\f0\fnil\fcharset0 Courier New;}}  \viewkind4\uc1\pard\lang1033\b\f0\fs36 The Planets Table\par          .          .          . 

Also note that Ive placed the RTF codes immediately after the <xsl:template> element, because RTF documents must start with RTF codes from the very beginning; if I had begun inserting RTF codes on the next line, like this:

 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="">      <xsl:output method="text"/>      <xsl:template match="/PLANETS">  {\rtf1\ansi\deff0{\fonttbl{\f0\fnil\fcharset0 Courier New;}}  \viewkind4\uc1\pard\lang1033\b\f0\fs36 The Planets Table\par          .          .          . 

then the RTF output file would have started with a newline character, which would throw off the RTF application (such as, possibly, Microsoft Word).

Outputting XHTML

W3C introduced XHTML to succeed HTML, but neither XSLT 1.0 nor the XSLT 1.1 working draft have any special support for XML-to-XHTML transformations. That support is supposed to be coming in XSLT 2.0. However, you can still create XHTML documents with XSLT processors.

More on XHTML

If you want to learn more about XHTML, take a look at Inside XML . Or you can go to the source: the W3C XHTML 1.0 recommendation at, as well as the XHTML 1.1 recommendation at

In addition to making sure your document adheres to the rules for XHTML (such as no standalone attributes, quoting all attribute values, using lower-case characters for markup, making sure every start tag has a corresponding closing tag, making sure the document is well-formed XML, and so on), the main issue is to make sure that a <!DOCTYPE> element appears in the result document.

Here are the <!DOCTYPE> elements you use with the three types of XHTML 1.0strict, transitional, and frameset (see Inside XML for information on how these versions are different):

 <!DOCTYPE html       PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"       "">  <!DOCTYPE html       PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"       "">  <!DOCTYPE html       PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"       ""> 

And heres the <!DOCTYPE> element for XHTML 1.1:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"       ""> 

<!DOCTYPE> Elements and HTML 4.01

Strictly speaking, even HTML documents are supposed to start with a <!DOCTYPE> element. Officially, there are three forms of HTML 4.01: strict, transitional, and frameset. Here are the complete <!DOCTYPE> elements for those versions: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" ""> , <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ""> , and <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" ""> . If youre producing rigidly correct HTML documents, consider adding this element to your documents. For more information, see

You can use the <xsl:output> elements doctype-system and d octype-public attributes to create a <!DOCTYPE> element if you set the output method to XML. Heres the <xsl:output> element that creates the <!DOCTYPE> element for transitional XHTML 1.0:

 <xsl:output method="xml"      doctype-system=""      doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" indent="yes"/> 

Heres the full stylesheet that uses this <xsl:output> element to convert planets.xml into a valid XHTML document, planets.html:

Listing 6.5 Transforming planets.xml to XHTML
 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="">  <xsl:output method="xml"      doctype-system=""      doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" indent="yes"/>      <xsl:template match="/PLANETS">          <html>              <head>                  <title>                      The Planets Table                  </title>              </head>              <body>                  <h1>                      The Planets Table                  </h1>                  <table>                      <tr>                          <td>Name</td>                          <td>Mass</td>                          <td>Radius</td>                          <td>Day</td>                      </tr>                      <xsl:apply-templates/>                  </table>              </body>          </html>      </xsl:template>      <xsl:template match="PLANET">         <tr>            <td><xsl:value-of select="NAME"/></td>            <td><xsl:apply-templates select="MASS"/></td>            <td><xsl:apply-templates select="RADIUS"/></td>            <td><xsl:apply-templates select="DAY"/></td>         </tr>     </xsl:template>      <xsl:template match="MASS">          <xsl:value-of select="."/>          <xsl:text> </xsl:text>          <xsl:value-of select="@UNITS"/>      </xsl:template>      <xsl:template match="RADIUS">          <xsl:value-of select="."/>          <xsl:text> </xsl:text>          <xsl:value-of select="@UNITS"/>      </xsl:template>      <xsl:template match="DAY">          <xsl:value-of select="."/>          <xsl:text> </xsl:text>          <xsl:value-of select="@UNITS"/>      </xsl:template>  </xsl:stylesheet> 

Heres the resulting XHTML file:

 <?xml version="1.0" encoding="UTF-8"?>  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"      "">  <html>      <head>          <title>              The Planets Table          </title>      </head>      <body>          <h1>              The Planets Table          </h1>          <table>              <tr>                  <td>Name</td>                  <td>Mass</td>                  <td>Radius</td>                  <td>Day</td>              </tr>              <tr>                  <td>Mercury</td>                  <td>.0553 (Earth = 1)</td>                  <td>1516 miles</td>                  <td>58.65 days</td>              </tr>              <tr>                  <td>Venus</td>                  <td>.815 (Earth = 1)</td>                  <td>3716 miles</td>                  <td>116.75 days</td>              </tr>              <tr>                  <td>Earth</td>                  <td>1 (Earth = 1)</td>                  <td>2107 miles</td>                  <td>1 days</td>              </tr>          </table>      </body>  </html> 

This document, planets.html, validates as well-formed and valid transitional XHTML 1.0, according to the W3C HTML and XHTML validation program, which is at Note that because XHTML documents are also well-formed XML documents, you use the XML output method, so this transformation is not too difficult; the only issue that takes a little thought is creating the <!DOCTYPE> element.

Inside XSLT
Inside Xslt
ISBN: B0031W8M4K
Year: 2005
Pages: 196

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: