Matching Tags with Attributes


XML, XPath, XSL, and StyleScript

All of our examples thus far are based on several technologies that you must understand before moving any further. These technologies include XML, XPath, XSL, and StyleScript. In this section, we discuss each of these technologies and explain how they work along with Resin to provide dynamic content to site users.

XML

You write XTP pages using HTML and other user-defined tags. For the most part, the XTP page can be fundamentally broken down into a format that resembles XML. By this we mean there are tags arranged in a pseudo-hierarchy, with attributes and enclosed values for some of the tags.

When the Resin server is presented with an XTP page, its first task is to parse the XML. Parsing the XML allows the system to "look" at each of the tags and determine if any action should take place. The parsing can be accomplished in two ways. The first is called the Document Object Model (DOM). In the DOM parsing methodology, a DOM tree is created that represents the entire XTP page. An alternative parsing method, called SAX, doesn't create an internal data structure but instead calls defined methods when various pieces of the XML are recognized. For instance, a method is called when a beginning tag is recognized.

Once the XTP page has been parsed using DOM, you can use a technology called XPath to match the nodes in the tree.

XPath

XPath is a specification-based language created for the express purpose of finding nodes in a DOM tree. As a defined language, XPath can be used independently of other technologies like XSL. The primary semantics defined in XPath revolve around matching patterns. The following is an explanation of the core patterns. Eventually, the patterns are used in either XSL or Style-Script to provide functionally to the system. As we examine the XPath pattern-matching syntax, consider the following example XML file:

 <HTML> <BODY>   <table border='1'>     <doTableHeader/>     <handleRow/>   </table>   <table>     <doTable2Header/>     <handleRow value='0'/>     <footer>2</footer>   </table> </BODY> </HTML> 

Although we haven't looked at XSL much yet, let's use the <xsl:template match='<pattern>' /> tag for our examples. This tag defines an action that needs to take place when the pattern found in the match attribute is successful. As mentioned, the following list provides an overview of the XPath pattern-matching syntax available to the developer when writing XSL.

  • /—Used as an absolute path to nodes within an XML document. For example:

          /HTML      /HTML/BODY/table 

    /HTML represents the root element of our document. The string /HTML/BODY/table drills down into the document and selects the first <table> tag.

  • //—Used to select all nodes. For example:

          //table      /table//handleRow 

    The first pattern example selects all <table> tags in the document. The second example pulls all of the handleRow tags but only when associated with a table tag. If there is a handleRow tag outside a table tag, it will not be returned.

  • <node>—Selects all elements within the document having a nodeName value of 'node'. For example:

        <xsl:template match='handleRow'>    <xsl:template/> 

    When executed against our example document, the template matches on two <handleRow> tags. If we had another tag in the document called <handleRows>, it would not be matched because no wildcards are assumed.

  • *—Selects all elements within the document. For example:

        <xsl:template match='//*'>    <xsl:template/> 

    This pattern returns all of the tags in the document. You can also use the * as a wildcard. For example:

        <xsl:template match='/table/*'>    <xsl:template/> 

    This pattern selects all nodes under either of the <table> tags. You can place the wildcard between tags as well:

        <xsl:template match='/HTML/*/table'>    <xsl:template/> 

  • [<criteria>]—Selects a node based on criteria. For example:

        /table[doTableHeader]    /table[1]    /table[footer=2]    /table[last()]    *[@border='1'][position()=last()-1] 

    In the first example, we are matching all <table> tags where one of the children is a doTableHeader tag. The second example matches <table> tags—but only the first one found in the document. The third example also matches <table> tags but a footer tag must be present and the value of the footer tag must be 2. In the fourth example, we are taking advantage of XPath functions available to the developer. (We list these functions later in this section.) For this match, only the very last <table> tag is used in the template. Finally, in the last example, we are matching all tags in the document but instead of just one criterion we have two. The first says that the matched tag must have an attribute called border set equal to 1, and the second criterion says the matched tag must be the second-to-last one found in the document.

  • .—Selects the current node. For example:

        /table/. 

    When you want the value of a node to be returned, use the . character to signal the current node.

  • ..—Selects a parent node. For example:

        /table/handleRow/../footer 

    In this example, the .. pattern is used to move back up the tree hierarchy for the table node.

  • |—Used to match one node or another. For example:

        /table/handleRow | /table/handleRow2 

    If you need to match two different nodes but perform the same action, use the I operator. In this example, we match on both handleRow and handleRow2 tags found as children to a <table> tag.

  • @<attribute>—Selects all of the attributes from a specified element. For example:

        <xsl:template match='handleRow[@value]'>    <xsl:template match='//@border' >    <xsl:template match='handleRow[@value=2]' > 

    In this first example, we are looking for all handleRow tags where a value attribute is present. The pattern doesn't care what the value of the attribute is—just that it exists. In the second example, we attempt to match all tags in the document that have border attributes within them. In the third example, the matched tag must be called handleRow and have an attribute set equal to 2.

  • @*—Selects all attributes for the current node. For example:

        <xsl:template match='handleRow[@*]' > 

    If you need to match on the handleRow regardless of the attributes, use the @* wildcard.

  • node()—Used to match a DOM node. For example:

        <xsl:value-of select='node()' /> 

    In this example, we use the <xsl:value-of> tag to obtain the value of the current node using the node() function.

  • text()—Used to match a text node. For example:

        <xsl:value-of select='text()' /> 

    In this example, we use the text() function to output the text() of the current node.

  • comment()—Used to match a comment node. For example:

        <xsl:value-of select='comment()' /> 

    The comment() function is used to pull any comment associated with the current node.

  • processing-instruction()—Used to match a processing instruction node. For example:

        <xsl:value-of select='processing-instruction()' /> 

    You can obtain processing instructions by using the processing-instruction() function.

Expressions

In most of the pattern-matching strings, you can use expressions to further clarify and narrow the selection of nodes in the document. Table 5.1 lists operators are available for formulating expressions.

Table 5.1: Available Operators

OPERATOR

DESCRIPTION

+

Addition

-

Subtraction

*

Multiplication

div

Division

mod

Modulus (division remainder)

=

Like (equal)

!=

Not like (not equal)

<

Less than

<=

Less or equal

>

Greater than

>=

Greater or equal

or

or

and

and

For example, we can match based on the value of an attribute:

 //table[@border > '5'] 

This code matches when a <table> tag is found that has a border attribute greater than 5.

XPath Functions

In several of our examples, we use XPath functions such as last() and position() to give a level of dynamic selection to the processing. Table 5.2 lists the available functions.

Table 5.2: XPath Functions

FUNCTION NAME

PURPOSE

boolean(<object>)

Returns a Boolean value from converting <object>.

ceiling(<number>)

Returns the closest integer greater than <number>.

concat(<string1, string2, ...>)

Returns a new string by concatenating the supplied strings.

contains(<srcstring, substring>)

Returns True if the substring is found within the srcstring.

count(<node-set>)

Returns a total count of all nodes matching the supplied node-set pattern.

false()

Returns a value of False.

loor(<number>)

Returns the closest integer less than <number>.

id(<ref>)

Returns the node having id attribute equal to <ref>.

if(<condition>, <a>, <b>)

If <condition> is true, returns <a>, else returns <b>.

lang(<language>)

Returns True if xml:lang of context node is equal to <language>.

last()

Returns the total count of nodes matching the current pattern.

local-part(<node>)

Returns the local part of <node>'s name.

name(<node>)

Returns <node>'s name.

namespace(<node>)

Returns <node>'s namespace URL.

normalize-space(<string>)

Returns a new string with normalized whitespace in <string>.

number(<object>)

Returns a Java double based on converted <object>.

round(<number>)

Returns <number> rounded to the nearest integer.

starts-with(<srcstring>, <headstring>)

Returns True if <srcstring> starts with <headstring>.

string(<object>)

Returns a new string based on <object>.

string-length(<string>)

Returns the length of <string>.

substring-after(<srcstring>, <substring>)

Returns a new string using the substring of <srcstring> after the matching <substring>.

substring-before(<srcstring>, <substring>)

Returns a new string using the substring of <srcstring> before the matching <substring>.

sum(<node-set>)

Returns a number based on the sum of all nodes designated by <node-set>.

translate(<srcstring>, <from>, <to>)

Returns a new string after converting characters using Unix 'tr' functionality.

true()

Returns True.

Many of the functions are used in XSL tags like <xsl:value-of> as well as in <xsl:template>. For example:

 <xsl:template match="/table[if(@border>'5', bigTag, smallTag)]" >  <xsl:value-of select="count(@border)" /> </xsl:template> 

XSL

Now that you know all about matching tags in your XTP pages, let's look at the tags available in XSL that allow you to do something useful with the matches found. XSL consists of various tags starting with the prefix <xsl:. The following list of tags provides you with a steppingstone to fully utilizing the power found in XSL.

  • <xsl:apply-imports>—Allows an overridden XSL template to be used from an import when the template has been redefined in the current style sheet. For example:

        <?xml version="1.0" encoding="ISO-8859-1"?>    <xsl:stylesheet version="1.0"    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">    <xsl:import href="standard.xsl"/>    <xsl:template match="account">     <font color='blue'>       <xsl:apply-imports/>     </font>    </xsl:template>    </xsl:stylesheet> 

In this example, we import a style sheet called standard.xsl. In standard.xsl, there is a template with a match='account'. The style sheet defined here also has a template with a match on account. By using the <xsl:apply-imports/> tag, we can output the <font> HTML, then use the template defined in standard.xsl and finally close the </font> tag.

  • <xsl:apply-templates select="" mode="">—Called when the child nodes of the current node should be evaluated before proceeding with the actions defined for the current node. Here are its attributes:

    • select—The pattern matching for the nodes to process.

    • mode—Distinguishes between multiple templates of the same pattern. For example:

       <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="account">   <h1><xsl:apply-templates select="name"/></h1> </xsl:template> <xsl:template match="name">  <xsl:value-of select="name"/> </xsl: template> </xsl:stylesheet> 

In this example, we match on the account node and then attempt to match any child node with the name of 'name'.

  • <xsl:attribute name="" namespace="">—Adds a new attribute to the current element. Here are its attributes:

    • name—The name of the attribute.

    • namespace—Optional namespace for the attribute. For example:

       <account>   <xsl:attribute name="picture">     <xsl:value-of select="images/pic" />   </xsl:attribute> </account> 

This example shows how to add a new attribute to the account tag.

  • <xsl:attribute-set>—Creates a new attribute set for the current style sheet. It has one attribute:

    • name—The name of the attribute-set. For example:

       <xsl:attribute-set name="font">  <xsl:attribute name="fname">Arial</xsl:attribute>  <xsl:attribute name="size">18px</xsl:attribute>   <xsl:attribute name="color">blue</xsl:attribute> </xsl:attribute-set> 

In this example, we create an attribute set that includes the name of the set and individual <xsl:attribute> tags.

  • <xsl:call-template>—Performs a call to a specific template passing the current node. It has one attribute:

    • name—The name of the template you want to call. For example:

       <xsl:template match="address">   <xsl:call-template name="city"/> </xsl:template> 

  • <xsl:choose>—Defines a switch-like structure with multiple if blocks. For example:

        <?xml version="1.0" encoding="ISO-8859-1"?>    <xsl:stylesheet version="1.0"    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">    <xsl:template match="/">      <html>      <body>       <h2>Accounts</h2>       <table border="1">        <tr bgcolor="#9acd32">          <th>Number</th>         <th>Name</th>       </tr>        <xsl:for-each select="accounts">        <tr>             <td><xsl:value-of select="Number"/></td>               <xsl:choose>              <xsl:when test="number&gt; '99910 ' ">               <td bgcolor="red">              <xsl:value-of select="name"/></td>            </xsl:when>            <xsl:otherwise>              <td><xsl:value-of select="name"/></td>            </xsl:otherwise>            </xsl:choose>          </tr>          </xsl:for-each>        </table>      </body>      </html>    </xsl:template>    </xsl:stylesheet> 

This code uses the <xsl:choose> tag to display an account's number and name in a table. If the account number is greater than 99910, then the name is highlighted.

  • <xsl:comment>—Creates a new comment for the current element. For example:

        <xsl:comment> This is a comment </xsl:comment> 

  • <xsl:copy use-attribute-sets="">—Copies the current node only to the output. It has one attribute:

    • use-attribute-sets—A comma-delimited list of sets to apply to the output. For example:

       <xsl:template match="city">  <xsl:copy>    <xsl:apply-templates/>  </xsl:copy> </xsl:template> 

This example uses the <xsl:copy> tag to copy all child nodes of the city node to the output without any processing.

  • <xsl:copy of>—Copies the specified subtree to the output. It has one attribute:

    • select—The node pattern to send to the output. For example:

       <xsl:variable name="header">  <tr>  <th>Name</th>  <th>Number</th>  </tr> </xsl:variable> <xsl:template match="/">   <html>   <body>   <table>   <xsl:copy-of select="$header" />  </table>  </body>  </html> </xsl:template> 

In this example, we define an XSL variable and use <xsl:copy-of> to output the variable's contents as needed.

  • <xsl:element>—Creates a new element. It has one attribute:

    • name—The name of the element. For example:

       <xsl:template match="/">   <xsl:for-each select="account">  <xsl:element name="accountnumber">  <xsl:value-of select="number" /> </xsl:element>   <br/>  </xsl:for-each> </xsl:template> 

This example looks through all of the nodes in the document with the name account. For each of those nodes, a new node is created in the DOM called accountnumber, with a value associated with the number node.

  • <xsl:for-each select="">—Loops through all nodes matching the specified child pattern. It has one attribute:

    • select—The node you want to loop through. For example:

       <xsl:template match="/">  <xsl:for-each select="account">     <xsl:value-of select="number" />  </xsl:for-each> </xsl:template> 

The <xsl:for-each> tag is very useful in that it allows the style sheet to loop through all of the nodes based on a specific pattern match.

  • <xsl:if test="">—Produces selected output depending on the evaluation of a condition. It has one attribute:

    • test—The condition that determines execution. For example:

          <xsl:if test="account&gt;'99910'">     <tr>             <td><xsl:value-of select="name"/></td>             <td><xsl:value-of select="number"/></td>           </tr>   </xsl:if> 

Here the <xsl:if> tag is used to determine whether or not specific values are sent to the output.

  • <xsl:import href="">—Imports a new style sheet at the specified location in the current file. It has one attribute:

    • href—The URI for the style sheet you want to import. For example:

       <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:import href="newXSL.xs1"/> </xsl:stylesheet> 

In this example, we import an XSL style sheet called newXSL.xsl into the current one.

  • <xsl:param name="" select="">—Creates a new XSL parameter. Its attributes are:

    • name—The name of the variable.

    • select—An optional default value for the variable

       <xsl:variable name="header">   <tr>   <th>Name</th>  <th>Number</th>   </tr> </xsl:variable> 

In this example, we created a variable called header. We can use the variable throughout the XSL style sheet to display header information by using the <xsl:param> tag.

  • <xsl:processing-instruction name="">—Creates a new processing instruction. It has one attribute:

    • name—The name of the processing instruction you want to add. For example:

       <xsl:processing-instruction name="xml-stylesheet"> href="newstyle.css" type="text/css" </xsl:processing-instruction> 

In this example, the processing instruction xml-stylesheet is added to the DOM.

  • <xsl:sort>—Sorts nodes found in <xsl:apply-templates> or <xsl:for-each> based on the specified select. Its attributes include:

    • select—Nodes you want to sort.

    • lang—Language you want to use in the sort.

    • data-type—The type of date (text or number).

    • order—Ascending or descending.

    • case-order—Upper-first or lower-first. For example:

       <xsl:for-each select="accounts">       <xsl:sort select="number"/>      <tr>     <td><xsl:value-of select="name" /></td>   </tr> </xsl:for-each> 

Here we find all of the accounts, sort them by number node value, and display the name for each account.

  • <xsl:stylesheet>—Required top-level element of an XSL style sheet. Its attributes are:

    • version—The version of the style sheet.

    • extension-element-prefixes—A list of namespace prefixes sent to output.

    • exclude-result-prefixes—A list of namespace prefixes not sent to output.

    • id—A unique name for the style sheet. For example:

       <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

  • <xsl:template>—An XSL construct for defining actions based on the matching pattern. Its attributes are:

    • name—The name of the template.

    • match—The node pattern you want to match for this template.

    • mode—A unique mode name for possible duplicate templates.

    • priority—The priority you want to apply to this template if multiple ones exist. For example:

       <xsl:template match="/">   <xsl:for-each select="account">     <xsl:value-of select="number" />   </xsl:for-each> </xsl:template> 

  • <xsl:text>—Copies text directly to output. For example:

     <xsl:text>And I can't do that,</xsl:text> 

  • <xsl:value-of select=""disable-output-escaping="">—Evaluates select and copies the result to the output. Its attributes are:

    • select—The node for which you want to display the value.

    • disable-output-escaping—Specifies yes or no; if no, then < would be &lt; instead of <. For example:

       <xsl:template match="accounts">   <tr>   <td><xsl:value-of select="name"/></td>  <td><xsl:value-of select="state"/></td>  </tr> </xsl:template> 

In this example, values are displayed for the name and state nodes defined as children under the accounts node.

  • <xsl:variable>—Assigns an XSL variable. It has one attribute:

    • name—The name of the variable. For example:

       <xsl:variable name="header">  <tr>  <th>Name</th>  <th>Number</th>   </tr> </xsl:variable> 

In this example, we created a variable called header. We can use the variable throughout the XSL style sheet to display header information by using the <xsl:param> tag.




Mastering Resin
Mastering Resin
ISBN: 0471431036
EAN: 2147483647
Year: 2002
Pages: 180

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