|
||||||||
| Chapter 6 - We Want Results! | |
| XSLT For Dummies | |
| by Richard Wagner | |
| Hungry Minds 2002 | |
Renaming an ElementRenaming an element is another technique that involves the use of literal text and xsl:value-of combination. Suppose, for example, that I want to rename the taste element to description in the coffee-light.xml . Within the stylesheet, I can create a single template rule to perform this operation:
<!-- coffee-rename.xsl --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <!-- Rename taste to description --> <xsl:template match="taste"> <description><xsl:value-of select="."/></description> </xsl:template> </xsl:stylesheet> The template rule uses a match pattern of taste to return all taste elements. The xsl:value-of instruction, with its select value of . , converts the content of each taste element to a string. The result is the following document: <?xml version="1.0" encoding="utf-8"?> <coffee name="Guatemalan Express" origin="Guatemala"> <description>Curiously Mild And Bland</description> <price>11.99</price> <availability>Year-round</availability> <bestwith>Breakfast</bestwith> </coffee>
|
|||||||||||
|
||||||||
| Chapter 6 - We Want Results! | |
| XSLT For Dummies | |
| by Richard Wagner | |
| Hungry Minds 2002 | |
Removing an Element
Because XSLTs built-in templates automatically add the content of elements, you frequently have occasions when you need to prevent an element from appearing in the result document. XSLT doesnt have a remove instruction, but you can ensure an element doesnt appear in the transformation by using one of two
Explicitly removing an element
The first technique is to explicitly delete an element by defining an empty template rule and using the element as the rules match pattern. An
empty template rule
is one that has a match pattern defined but no
<xsl:template match="dog"/>
An empty template rule
<!-- coffee-remove.xsl --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <!-- Remove taste element --> <xsl:template match="taste"/> <xsl:template match="bestwith"/> <!-- Copy everything else over --> <xsl:template match="@*node()"> <xsl:copy> <xsl:apply-templates select="@*node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> By defining an empty template rule for the taste and bestwith elements, I remove these as part of the result. I can then use my "catch-all" template rule to simply copy everything else over. The XML code generated from the transformation looks like: <?xml version="1.0" encoding="utf-8"?> <coffees> <region name="Latin America"> <coffee name="Guatemalan Express" origin="Guatemala"> <price>11.99</price> <availability>Year-round</availability> </coffee> <coffee name="Costa Rican Deacon" origin="Costa Rica"> <price>12.99</price> <availability>Year-round</availability> </coffee> </region> <region name="Africa"> <coffee name="Ethiopian Sunset Supremo" origin="Ethiopia"> <price>14.99</price> <availability>Limited</availability> </coffee> <coffee name="Kenyan Elephantismo" origin="Kenya"> <price>9.99</price> <availability>Year-round</availability> </coffee> </region> </coffees> Remember Because the taste and bestwith elements dont contain any other elements, running empty template rules on them only removed these two elements and nothing else. However, keep in mind, if you create an empty template rule for an element with children, the empty rule removes the specified element along with its children during the transformation. For example, running <xsl:template match="coffees"/> on the coffee.xml file generates an empty document, because coffees contains all other elements.
Implicitly removing an element
You can also implicitly remove an element by
<!-- coffee-remove2.xsl --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <selectcoffees> <xsl:apply-templates/> </selectcoffees> </xsl:template> <!-- Copy coffee and its price and availability children --> <xsl:template match="coffee"> <coffee> <price><xsl:apply-templates select="price"/></price> <availability><xsl:apply-templates select="availability"/></availability> </coffee> </xsl:template> </xsl:stylesheet> A new document element named selectcoffees is created in the first template. The start and end tags of selectcoffees is plugged in before and after the xsl:apply-templates instruction, which is run on all descendants of the root node (the / match pattern). The coffee template rule reconstructs the coffee element, but it does so by using literal text to redefine the price and availability tags and by using xsl:apply-templates to generate the child elements content. Notice that the context for these xsl:apply-templates instructions is very specific because the select attribute is defined for them, applying just the price and availability elements. As a result, taste and bestwith elements are summarily dropped from the result document. (Boy, XSLT is a tough business!) I also want to get rid of the region element, but because it doesnt have any text nodes defined as content, I simply allowed the built-in template rule to do its thing; in doing so, the region element tags arent added to the result document. The end result is a new selectcoffees structure: <?xml version="1.0" encoding="utf-8"?> <selectcoffees> <coffee> <price>11.99</price> <availability>Year-round</availability> </coffee> <coffee> <price>12.99</price> <availability>Year-round</availability> </coffee> <coffee> <price>14.99</price> <availability>Limited</availability> </coffee> <coffee> <price>9.99</price> <availability>Year-round</availability> </coffee> </selectcoffees>
|
|||||||||||