Working with the xsl:template

xsl:template is perhaps the most important top-level element in an xsl stylesheet. While all the other elements add to a stylesheet, xsl:template is its heart and soul.

Note

The remaining sections in this chapter all use the XML Document defined in Listing 5.2 unless otherwise noted.


Figure 5.2 shows a graphical representation of Listing 5.2. Examining Figure 5.2, we see that its root contains two elements—the REListing element and the xsl-stylesheet processing instruction. Don't forget that the root of the document is not the same as the root element. The document root contains the stylesheet element and the root element. The root element, in our case the REListing element, contains all the document's children. Specifically, the REListing element contains a Header, a Trailer (both optional), a State, and some number of County elements. Each County element contains some number of Town elements. And Towns contain some number of, among other things, Listing elements. At the bottom of the hierarchy, Listings contain a number of data items representing each listing such as Price, Address, and other information important to real estate.

Figure 5.2. A graphical representation of the XML document in Listing 5.2.


To use XSL, one must understand how XSL Transformations function. XSL Transformations work by applying one or more template rules to an XML document. Template rules then work by looking for matches on XML elements and then exercising the remainder of the rule on the matching element or elements in the order encountered. If many elements match the rule, the rule is applied to each in the order it appears. In addition, a template rule might contain instructions to continue to match on children of the current element. In this way, XSL Transforms work sequentially throughout a document (although as we will see later they can be applied other ways) and recursively through the children of an element.

All xsl:template rules follow the pattern

<xsl:template match="some match criteria">
    Some replacement text and/or additional rules
</xsl:template>

The simplest xsl:template rule, one that causes all data in an XML document to be ignored, can be written as follows:

<xsl:template match="/|*"/>

Simply stated, match any document or any text, and do nothing.

Specifically, each xsl:template rule contains match criteria as well as replacement text and/or more rules. For example, we can easily imagine an XSL stylesheet that translates book text into HTML. We might want to replace each instance of the tag <chapter> with <H1>Chapter</H1>. We could do this easily with the following xsl:template rule:

<xsl:template match="chapter">
<H1>Chapter</H1>
</xsl:template>

Of course, this is not a very useful rule. What we are more likely to want to do is insert the chapter tag's value along with some text. The following rule does just that for our real estate listings. Each time a Listing element is encountered, we prefix it with the <H1> and then the word Listing and finally the contents of the listing itself using xsl:value-of (more on this element of XSL shortly) followed by </H1>.

<xsl:template match="Listing">
<H1>Listing: <xsl:value-of select="."/></H1>
</xsl:template>

Code Listing 5.2. REListing.xml—An XML Document Representing Real Estate Listings
<?xml version="1.0" encoding="UTF-8" ?>
<!--
A XML Document representing real estate listing
Al Saganich for Macmillan USA
-->

<!DOCTYPE REListing [
<!ELEMENT REListing (Header,State,County*,Trailer?)>
<!ELEMENT Header (#PCDATA)>
<!ELEMENT State (#PCDATA)>
<!ELEMENT Trailer (#PCDATA)>
<!ELEMENT County (Town*)>
<!ATTLIST County
Name CDATA #REQUIRED
Description CDATA #REQUIRED>
<!ELEMENT Town (TownName, TownDescription, Listing*)>
<!ATTLIST Town Zipcode CDATA "Unknown">
<!ELEMENT TaxRate (#PCDATA)>
<!ELEMENT TownName (#PCDATA)>
<!ELEMENT TownDescription (#PCDATA)>
<!ELEMENT Listing (ListingBroker, Type, ListPrice,Addr,
     YearBuilt?,Bedrooms?, Baths?, SpecialFeatures?, Lotsize,Description)>
<!ELEMENT ListingBroker (#PCDATA)>
<!ELEMENT Type (#PCDATA)>
<!ATTLIST Type
PropType CDATA #REQUIRED
PropType (residential|commercial|land|farm|other) "residential">
<!ELEMENT Addr (#PCDATA) >
<!ELEMENT YearBuilt (#PCDATA)>
<!ELEMENT Bedrooms (#PCDATA)>
<!ELEMENT Baths (#PCDATA)>
<!ELEMENT SpecialFeatures (#PCDATA)>
<!ELEMENT Lotsize (#PCDATA)>
<!ATTLIST Lotsize Units (acres|sq.feet) "sq.feet">
]>

<REListing>
<Header>Real Estate Listings for Middlesex and Worchester Counties</Header>
<State>Massachusetts</State>
<County Name="Worchester" Desc="A wondeful county in Central Massachusetts">
<Town>
<Name Zipcode="01464">Shirley</Name>
<TaxRate>14.86</TaxRate>
<TownDescription>A small rural town of approximately 7000
. . .   <!--
Note that the complete contents of listing 5.2 can be found
In the chp7 subdirectory of the CDRom as REListing.xml
         -->
. . .
<Listing>
<ListingBroker>Successful Home Sellers</ListingBroker>
<Type PropType="land">Land</Type>
<ListingPrice>1,249,999</ListingPrice>
<Addr>Groton Country Wood Road</Addr>
<SpecialFeatures>Open farm land</SpecialFeatures>
<Lotsize Units="acres">25</Lotsize>
<Description>A wonderful site ready for the right developer!</Description>
</Listing>
</Town>
</County>
</REListing>

Templates Are Recursive

One of the more important concepts to understand about XML is that it is recursive in nature. xsl:template rules are for the most part also recursive via the xsl:apply-templates element. What exactly does xsl:apply-templates do? Well, most times XML data is represented as a hierarchy of data within data. We saw in Figure 5.2 that Countys contained Towns, Towns contained Listings, and Listings contained a number of data items. Earlier, we showed a simple example (which can be found on the CD-ROM as re-listing.xsl) that manipulated Listings. But suppose we wanted to manipulate Towns rather than Listings? A rule such as the following appears to do the trick:

<xsl:template match="Town">
<h1>Town: <xsl:value-of select ="."/></h1>
</xsl:template>

However, what this rule really does is bracket Towns and all their underlying data elements in <h1>...</h1>. Perhaps what we really wanted was to bracket only the town name and then apply other template rules to each Listing child.

The following rule does the trick but does a little more as well, thanks to the default rules, which we'll see more of in a moment.

<xsl:template match="Town">
    <h1><xsl:value-of select="TownName"/> </h1>
    <xsl:apply-templates match="Listing"/>
 </xsl:template>

Default Rules

As I stated a moment ago the previous rule produced "a little more as well." Well, that "little more" came from the default rules. At first glance, default rules seem to be more of an inconvenience than anything else, causing output we didn't expect or want. However, if we look closely, we can see that it would be much more of an inconvenience to specify a rule for every single element within an XML document! There are two default rules within XSL that output something. They are

<xsl:template match="*|/">
    <xsl:apply-templates/>
<xsl:template>

which applies to any element or the root element and simply applies all other templates to it.

<xsl:template match="text()|@*")>
    <xsl:value-of select="."/>
</xsl:template>

which matches any text element or any attribute and outputs its contents.

There are other default rules as well. The following default rule matches processing instructions and comments and outputs nothing:

<xsl:template match="processing-instruction()|comment()"/>

We could easily override this rule to produce comments and processing instructions as follows:

<xsl:template match="processing-instruction()|comment()">
    <xsl:value-of select="."/>
</xsl:template>

One interesting note about these two rules is their order of application or precedence. Rule precedence defines which rule will be applied if two rules match a given input pattern. The default rules are of lowest precedence, treated as if they were the last rules encountered via xsl:import, and are overridden by any other rule with the same matching criteria. We will provide more examples of precedence in detail in the section "Precedence for Rules" later in this chapter.

We've now seen a few examples of XSL and how we can use it. Before we move on, let's see how we would actually attach a stylesheet to an XML document.

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

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