6.2. The <xsl:element> Instruction Element

The <xsl:element> instruction element provides a more structured approach to adding new XML elements directly to the output result tree. The following element model definition shows the correct structure of the <xsl:element> instruction element:

<!-- Category: instruction -->

<xsl:element

  name = { qname }

  namespace = { uri-reference }

  use-attribute-sets = qnames>

  <!-- Content: template -->

</xsl:element>

The <xsl:element> instruction element has three attributes, one of which is mandatory: the name attribute. The name attribute contains the element-type name of the new element in the result tree. This attribute is required because an element without an element-type name is not valid XML, and using the <xsl:element> implies that the output will be either XML or HTML.

Note

Using <xsl:element> when the output type is text will cause the new element's tags to be ignored (not even sent to the output). LREs will also be ignored. The output type is specified with the <xsl:output> element's method attribute, discussed in Chapter 10.


The optional namespace attribute permits the declaration of a URI, if the new element requires a namespace to be shown in the result. In addition, <xsl:element> contains the optional use-attribute-sets attribute, which allows the new element to reference a pre-determined set of attributes (see Section 6.4).

In our Markup City in Example 6-2, the <xsl:element> element could enable the city planners to begin drawing neighborhood grids.

The template rule shown adds houses to each block using the <xsl:element> with an element-type name (specified in the name attribute) of house. This may seem a little over-complicated, since the same effect can easily be accomplished using LREs as follows:

<xsl:template match="block">
      <block>
          <house>1</house>
          <house>2</house>
          <house>3</house>
          <house>4</house>
          <house>5</house>
   </block>
</xsl:template>

However, the advantage of using <xsl:element> instead of an LRE is that the name of the new element can be calculated using expressions, which are not allowed in the start or end tags of an LRE. The name attribute of <xsl:element> is interpreted by the XSLT processor as an AVT (see Section 6.6.1 for more information about AVTs). Using AVTs allows the content of the name attribute to be an XPath expression, as long as the value is surrounded by curly braces {}. For example, instead of naming our houses just house, we could compute the value of the element-type name using an expression:

<xsl:element name="{concat(translate(ancestor::thoroughfare/@name, ' ',
'-'), '-', 'house')}">

The result of this expression would return a different element-type name depending on which <thoroughfare> the <block> is in. The value of the name attribute of each <thoroughfare> is put through a translate() to convert the spaces to dashes. Then, the value is concatenated with a dash and the word “house.” The two new element-type names are <Whitesburg-Drive-house> and <Bankhead-house>.

Expressions are not allowed in an LRE name because the special characters in an expression are not valid XML and are not allowed in an element-type name. For example, if we wanted to just repeat the element <block> without typing "<block>," it would seem to make sense to use <name()> to extract the name of the element, but this would cause an error. This format is not a valid LRE because parentheses () are not allowed in element-type names, and the XSLT processor would attempt to interpret <name()> as a literal XML element. You could, however, use the name() function as follows:

<xsl:element name="{name()}">

Example 6-2. Using <xsl:element> to add houses to each block.
					INPUT:

<?xml version="1.0"?>
<parkway>
            <thoroughfare>Governor Drive</thoroughfare>
            <thoroughfare name="Whitesburg Drive">
                  <sidestreet name="Bob Wallace Avenue">
                         <block>1st Street</block>
                         <block>2nd Street</block>
                         <block>3rd Street</block>
                  </sidestreet>
                  <sidestreet>Woodridge Street</sidestreet>
            </thoroughfare>
            <thoroughfare name="Bankhead">
                  <sidestreet name="Tollgate Road">
                         <block>First Street</block>
                         <block>Second Street</block>
                         <block>Third Street</block>
                  </sidestreet>
                  <sidestreet>Oak Drive</sidestreet>
            </thoroughfare>
</parkway>
TEMPLATE RULE:

<xsl:template match="block">
      <block>
            <xsl:element name="house">1</xsl:element>
            <xsl:element name="house">2</xsl:element>
            <xsl:element name="house">3</xsl:element>
            xsl:element name="house">4</xsl:element>
            <xsl:element name="house">5</xsl:element>
      </block>
      </xsl:template>
OUTPUT:

<block>
<house>1</house>
<house>2</house>
<house>3</house>
<house>4</house>
<house>5</house>
</block>
      <!-- other blocks removed for brevity -->

Once new elements are created, using either <xsl:element> or LREs, you can add attributes as necessary using the <xsl:attribute> element. Note that <xsl:attribute> can also be used to add attributes to elements generated or copied from the input with other XSLT elements; its use is not restricted to just new elements.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset