Using XML Flow-Control Tags The XML flow-control tags enable your program to make decisions based on the results of XSL queries. The XML flow-control tags resemble some of the JSTL core tags. The <c:if> tag allows the core tag library to perform logic based on what's entered or stored in scoped variables. The XML tag library adds the tag <x:if>, which enables your program to conditionally execute other tags based on the result of an XPath expression. The <c:if> tag is not the only tag that has a counterpart in the XML tag library; the tags <c:otherwise>, <c:choose>, and <c:when> all have the XML counterparts <x:otherwise>, <x:choose>, and <x:when>. Using the <x:forEach> Tag The <x:forEach> tag works much like the <c:forEach> tag. Both tags allow you to iterate over a collection of values. As we discussed earlier, an XPath expression can return a collection of nodes, and the <x:forEach> tag allows you to iterate over those nodes. There is one form of the <x:forEach> tag: <x:forEach [var="varName"] select="XpathExpression"> body content </x:forEach>
The <x:forEach> tag accepts the following attributes:
|
select | N | An XPath expression that you want to iterate over. | var | Y | Specifies the scoped variable that will hold each iteration. |
The value placed in the variable�which is specified by the var attribute�contains all the values stored in the node. You can use <x:out> and <x:set> with relative XPaths that will obtain data from each member of the collection. So far, our examples have accessed only one student name at a time. Using the <x:forEach> tag, it is possible to iterate through entire branches of the XML file. Let's now look at an example that reads through the entire list of students and displays each student and his or her score. The output from this program is shown in Figure 8.4. Let's look at how this page is implemented. You'll find that using the <x:forEach> tag is similar to using the <c:forEach> tag that allows us to iterate over collections. Listing 8.5 shows how this page was constructed. Listing 8.5 Using the <x:forEach> Tag (foreach.jsp)<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jstl/xml" prefix="x" %> <html> <head> <title>For Each Examples</title> </head>
<body> <c:import var="students" url="students.xml" />
<x:parse var="doc" xml="${students}" />
<table border="1"> <tr> <th>First</th>
<th>Last</th>
<th>Points</th>
<th>Letter</th> </tr>
<x:forEach var="student" select="$doc/students/student"> <tr> <td> <x:out select="name/first" /> </td>
<td> <x:out select="name/last" /> </td>
<td> <x:out select="grade/points" /> </td>
<td> <x:out select="grade/letter" /> </td> </tr> </x:forEach> </table> </body> </html>
The program in Listing 8.5 begins by loading the student.xml file, just as the previous programs did: <c:import var="students" url="students.xml" /> <x:parse var="doc" xml="${students}" />
The student list is displayed in an HTML table. The following code sets up the header for this table: <table border="1"> <tr> <th>First</th> <th>Last</th> <th>Points</th> <th>Letter</th> </tr>
At this point, we must create the individual rows that display each of the students. This is done with the following <x:forEach> tag, which iterates over all student nodes contained in the XML file: <x:forEach var="student" select="$doc/students/student">
As the program iterates through the students branch of the XML file, it places each row in the student scoped variable we specified in the var attribute. As you can see, we're using the XPath query $doc/students/student. We use this code to display each student as a row in the table containing the first name, last name, grade points, and letter grade: <tr> <td> <x:out select="name/first" /> </td> <td> <x:out select="name/last" /> </td> <td> <x:out select="grade/points" /> </td> <td> <x:out select="grade/letter" /> </td> </tr>
Now we have only to end the <x:forEach> tag and the table: </x:forEach> </table>
Using the <x:if> Tag You use the <x:if> tag to evaluate the result of an XPath expression. This expression should result in a Boolean value. There are two forms of the <x:if> tag: // Syntax 1: Without a body, result copied to var <x:if select="XpathExpression" var="varName" [scope="{page|request|session|application}"]/> // Syntax 2: With conditional body content <x:if select="XpathExpression" [var="varName"] [scope="{page|request|session|application}"]> body content </x:if> <x:if select="PathExpression" [var="varName"] [scope="{page|request|session|application}"]> body content </x:if>
The first syntax uses an attribute, var, to specify a scoped variable to hold the true/false result of the comparison. The second form uses the body of the <x:if> tag to specify a block of the document that will be executed conditionally. Here are the attributes accepted by the <x:if> tag:
|
scope | N | If the var attribute is specified, the scope attribute specifies the scope of that variable. Defaults to page scope. | select | Y | The XPath expression that you want to evaluate. | var | N | A scoped variable that will receive the value of the expression being evaluated. This attribute is required if there is no body. |
As with many of the JSTL tags, you must provide a select attribute that specifies the XPath expression that you want to evaluate. You may optionally include a var attribute that specifies a scoped variable to store the result of the comparison. This scoped variable will receive the Boolean value true or false. If you include a var attribute, you can also specify a scope attribute that specifies the variable's scope. If the XPath expression evaluates to true, then the body of the <x:if> tag is executed. Using the <x:choose> Tag The <x:choose> tag works much like the <c:choose> tag. The <x:choose> tag allows you to nest several <x:when> and <x:otherwise> statements into a single comparison block. There is one form of the <x:choose> tag: <x:choose> body content (<x:when> and <x:otherwise> subtags) </x:choose>
There are no attributes to this tag. The <x:choose> tag will begin evaluating the <x:when> statements until one matches. Our program executes the first matching <x:when> tag and then exits the <x:choose> block. It is impossible for more than one <x:when> block to execute. If no <x:when> tag executes, the program executes an <x:otherwise> tag if one exists. Let's see an example of using the <x:choose> tag. This example extends our previous example by attaching a note to the score of each student. The program will display any one of several predefined messages. The message is determined by how well the user scored. We've shown the output from this program in Figure 8.5. This program uses the same iteration loop we used in the previous example. Listing 8.6 shows the contents of this page. Listing 8.6 The <x:choose> Tag (choose.jsp)<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %><%@ taglib uri="http://java.sun.com/jstl/xml" prefix="x" %> <html> <head> <title>For Each Examples</title> </head>
<body> <c:import var="students" url="students.xml" />
<x:parse var="doc" xml="${students}" />
<table border="1"> <tr> <th>First</th>
<th>Last</th>
<th>Points</th>
<th>Letter</th>
<th>Note</th> </tr>
<x:forEach var="student" select="$doc/students/student"> <tr> <td> <x:out select="name/first" /> </td>
<td> <x:out select="name/last" /> </td>
<td> <x:out select="grade/points" /> </td>
<td> <x:out select="grade/letter" /> </td>
<td> <x:choose> <x:when select="grade/points>90">You did great!</x:when>
<x:when select="grade/points>80">You did good!</x:when>
<x:when select="grade/points>75">You did ok.</x:when>
<x:when select="grade/points>70">Well, you passed.</x:when>
<x:otherwise>You failed</x:otherwise> </x:choose> </td> </tr> </x:forEach> </table> </body> </html>
We use the <x:choose> tag to display the note for each student: <x:choose>
The <x:choose> tag is similar to the <c:choose> tag. The primary difference is evident in the <x:when> tags. The <x:when> tags do not accept a test attribute; instead, they accept select attributes that specify an XPath expression that you want to evaluate. It is important that this XPath expression return a Boolean so that the <x:when> tags can take the most appropriate action. The program begins by checking whether see if the XPath expression given by grade/points>90 evaluates to true. If this expression does evaluate to true, then the program executes the body of the <x:when> tag and terminates the <x:choose> loop: <x:when select="grade/points>90">You did great!</x:when>
If the first <x:when> tag does not execute, the page continues to examine <x:when> tags until one matches: <x:when select="grade/points>80">You did good!</x:when> <x:when select="grade/points>75">You did ok.</x:when> <x:when select="grade/points>70">Well, you passed.</x:when>
If none of the <x:when> tags match, then our program executes the <x:otherwise> tag. If no <x:otherwise> tag exists, the <x:choose> tag will exit. The following <x:otherwise> tag causes the default message to appear: <x:otherwise>You failed</x:otherwise> </x:choose>
Using the <x:when> Tag The <x:when> tag is used in conjunction with the <x:choose> tag. The <x:when> tag checks to see whether the XPath expression evaluates to true; if it does, the program executes the body of the <x:when> tag. There is one form of the <x:when> tag: <x:when select="XpathExpression"> body content </x:when>
The <x:when> tag accepts one attribute:
|
select | N | An XPath expression that you want to evaluate. |
If the XPath expression evaluates to true, then the program executes the body of the <x:when> tag. If the XPath expression evaluates to false, then the next <x:when> tag is evaluated. The <x:when> tags are executed in the same order in which they are presented in the file. Only one <x:when> tag will execute per call to <x:choose>; the <x:choose> block exits after the first <x:when> tag matches. Using the <x:otherwise> Tag The <x:otherwise> tag works like a default <x:when> tag. If no other <x:when> tag evaluates to true in a <x:choose> block, then the <x:otherwise> tag will be executed. You should have only one <x:otherwise> tag per <x:choose> block. There is one form of the <x:otherwise> tag: <x:otherwise> conditional block </x:otherwise>
No attributes are accepted by the <x:otherwise> tag. You have to embed the code that you want executed within the body of the <x:otherwise> tag. |
No comments:
Post a Comment