The xsl:element Element: Creating New Elements at Run Time

The <xsl:element> Element: Creating New Elements at Run Time

You can create new elements with the <xsl:element> element, which is very useful if you need to determine a new elements name at run time.

This element has three attributes:

  • name (mandatory). Name of the element you want to create. Set to an attribute value template that returns a QName.

  • namespace (optional). The namespace URI of the new element. Set to an attribute value template returning a URI.

  • use-attribute-sets (optional). Specifies the attribute sets containing the attributes for this element. Set to a whitespace-separated list of QNames.

The <xsl:element> element contains a template body.

For example, say that I want to store the names of the planets in NAME attributes rather than in a <NAME> element in planets.xml, like this:

 <?xml version="1.0"?>  <?xml-stylesheet type="text/xml" href="planets.xsl"?>  <PLANETS>    <PLANET NAME="Mercury">        <MASS UNITS="(Earth = 1)">.0553</MASS>        <DAY UNITS="days">58.65</DAY>        <RADIUS UNITS="miles">1516</RADIUS>        <DENSITY UNITS="(Earth = 1)">.983</DENSITY>        <DISTANCE UNITS="million miles">43.4</DISTANCE><!--At perihelion-->    </PLANET>      .      .      . 

Suppose now that I want to use the value of that attribute to create new element names in the result document such as <Mercury> , <Venus> , and <Earth> :

 <?xml version="1.0" encoding="UTF-8"?>  <?xml-stylesheet type="text/xml" href="planets.xsl"?>  <PLANETS>      <Mercury>          <MASS UNITS="(Earth = 1)">.0553</MASS>          <DAY UNITS="days">58.65</DAY>          <RADIUS UNITS="miles">1516</RADIUS>          <DENSITY UNITS="(Earth = 1)">.983</DENSITY>          <DISTANCE UNITS="million miles">43.4</DISTANCE><!--At perihelion-->      </Mercury>          .          .          . 

In this case, I dont know the name of the output element until run time, so I cant just use a literal result element. I could cobble together a new element, treating it as text this way, where Im using the <xsl:text> elements disable-output-escaping attribute to output characters such as <:

 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  <xsl:output method="xml"/>    <xsl:template match="@*node()">      <xsl:copy>        <xsl:apply-templates select="@*node()"/>      </xsl:copy>    </xsl:template>    <xsl:template match="PLANET">      <xsl:text disable-output-escaping="yes">&lt;</xsl:text>      <xsl:value-of select="@NAME"/>      <xsl:text disable-output-escaping="yes">&gt;</xsl:text>      <xsl:apply-templates/>      <xsl:text disable-output-escaping="yes">&lt;/</xsl:text>      <xsl:value-of select="@NAME"/>      <xsl:text disable-output-escaping="yes">&gt;</xsl:text>    </xsl:template>  </xsl:stylesheet> 

But this way is clumsy and it treats markup as simple text. On the other hand, I could create a new element using the name of a planet with <xsl:element> , getting the name of the new planet from the name attribute this way:

Listing 6.6 Using <xsl:element>
 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  <xsl:output method="xml"/>    <xsl:template match="@*node()">      <xsl:copy>        <xsl:apply-templates select="@*node()"/>      </xsl:copy>    </xsl:template>  <xsl:template match="PLANET">      <xsl:element name="{@NAME}">          <xsl:apply-templates/>      </xsl:element>  </xsl:template>  </xsl:stylesheet> 

This is a lot cleaner and simpler. Here is the result, where Ive created the new elements, each with the name of a different planet and created at run time:

 <?xml version="1.0" encoding="UTF-8"?>  <?xml-stylesheet type="text/xml" href="planets.xsl"?>  <PLANETS>      <Mercury>          <MASS UNITS="(Earth = 1)">.0553</MASS>          <DAY UNITS="days">58.65</DAY>          <RADIUS UNITS="miles">1516</RADIUS>          <DENSITY UNITS="(Earth = 1)">.983</DENSITY>          <DISTANCE UNITS="million miles">43.4</DISTANCE><!--At perihelion-->      </Mercury>      <Venus>          <MASS UNITS="(Earth = 1)">.815</MASS>          <DAY UNITS="days">116.75</DAY>          <RADIUS UNITS="miles">3716</RADIUS>          <DENSITY UNITS="(Earth = 1)">.943</DENSITY>          <DISTANCE UNITS="million miles">66.8</DISTANCE><!--At perihelion-->      </Venus>      <Earth>          <MASS UNITS="(Earth = 1)">1</MASS>          <DAY UNITS="days">1</DAY>          <RADIUS UNITS="miles">2107</RADIUS>          <DENSITY UNITS="(Earth = 1)">1</DENSITY>          <DISTANCE UNITS="million miles">128.4</DISTANCE><!--At perihelion-->      </Earth>  </PLANETS> 

In this way, you can create new elements and name them when the XSLT transformation takes place.



Inside XSLT
Inside Xslt
ISBN: B0031W8M4K
EAN: N/A
Year: 2005
Pages: 196

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net