XML Tutorial/XSLT stylesheet/for each
Версия от 18:22, 25 мая 2010; (обсуждение)
Содержание
- 1 compares sorted and unsorted xsl:for-each element
- 2 for-each select="addressbook/address" and sort
- 3 for-each select=//address[generate-id(.)=generate-id(key(zipcodes, zip)[1])]
- 4 for-each select=preceding-sibling::address[zip=./zip]
- 5 Nested for-each loop with sorting
- 6 Output xml elements in for-each loop
- 7 The xsl:for-each element allows all nodes in a node-set to be processed according to the XSLT instructions nested inside the xsl:for-each element.
- 8 Use for-each loop to output list items
- 9 xsl:for-each instruction contains a template, which is applied to each node selected with select attribute.
compares sorted and unsorted xsl:for-each element
File: Data.xml
<?xml version="1.0" encoding="utf-8"?>
<data>
<AAA>
<BBB>
<CCC>A</CCC>
</BBB>
<BBB/>
<BBB/>
</AAA>
<AAA>
<BBB/>
<BBB>
<CCC>B</CCC>
<CCC>C</CCC>
<CCC>D</CCC>
<CCC>E</CCC>
</BBB>
</AAA>
</data>
File: Transform.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<TABLE border="1">
<TR>
<td>Position</TH>
<td>Last</TH>
<td>Name</TH>
</TR>
<xsl:for-each select="//AAA[last()]//CCC">
<TR>
<TD>
<xsl:value-of select="position()"/>
</TD>
<TD>
<xsl:value-of select="last()"/>
</TD>
<TD>
<xsl:value-of select="text()"/>
</TD>
</TR>
</xsl:for-each>
</TABLE>
<TABLE border="1">
<TR>
<td>Position</TH>
<td>Last</TH>
<td>Name</TH>
</TR>
<xsl:for-each select="//AAA[last()]//CCC">
<xsl:sort order="ascending" select="text()"/>
<TR>
<TD>
<xsl:value-of select="position()"/>
</TD>
<TD>
<xsl:value-of select="last()"/>
</TD>
<TD>
<xsl:value-of select="text()"/>
</TD>
</TR>
</xsl:for-each>
</TABLE>
</xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?><TABLE border="1"><TR><td>Position</TH><td>Last</TH><td>Name</TH></TR><TR><TD>1</TD><TD>4</TD><TD>B</TD></TR><TR><TD>2</TD><TD>4</TD><TD>C</TD></TR><TR><TD>3</TD><TD>4</TD><TD>D</TD></TR><TR><TD>4</TD><TD>4</TD><TD>E</TD></TR></TABLE><TABLE border="1"><TR><td>Position</TH><td>Last</TH><td>Name</TH></TR><TR><TD>1</TD><TD>4</TD><TD>E</TD></TR><TR><TD>2</TD><TD>4</TD><TD>C</TD></TR><TR><TD>3</TD><TD>4</TD><TD>B</TD></TR><TR><TD>4</TD><TD>4</TD><TD>D</TD></TR></TABLE>
for-each select="addressbook/address" and sort
File: Data.xml
<?xml version="1.0"?>
<!-- names.xml -->
<addressbook>
<address>
<name>
<title>Mr.</title>
<first-name>Doris</first-name>
<last-name>Smith</last-name>
</name>
<street>1234 Main Street</street>
<city>New York</city>
<state>WI</state>
<zip>48392</zip>
</address>
<address>
<name>
<title>Ms.</title>
<first-name>Jane</first-name>
<last-name>Lee</last-name>
</name>
<street>930-A Chestnut Street</street>
<city>Twincity</city>
<state>MA</state>
<zip>02930</zip>
</address>
</addressbook>
File: Transform.xslt
<?xml version="1.0"?>
<!-- namegrouper2a.xsl -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<addressbook>
<xsl:for-each select="addressbook/address">
<xsl:sort select="zip"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</addressbook>
</xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?><addressbook><address><name><title>Ms.</title><first-name>Jane</first-name><last-name>Lee</last-name></name><street>930-A Chestnut Street</street><city>Twincity</city><state>MA</state><zip>02930</zip></address><address><name><title>Mr.</title><first-name>Doris</first-name><last-name>Smith</last-name></name><street>1234 Main Street</street><city>New York</city><state>WI</state><zip>48392</zip></address></addressbook>
for-each select=//address[generate-id(.)=generate-id(key(zipcodes, zip)[1])]
File: Data.xml
<?xml version="1.0"?>
<addressbook>
<address>
<name>
<title>Ms.</title>
<first-name>Doris</first-name>
<last-name>Smith</last-name>
</name>
<street>707 New Way</street>
<city>New York</city>
<state>ME</state>
<zip>00218</zip>
</address>
<address>
<name>
<first-name>Jane</first-name>
<last-name>Lee</last-name>
</name>
<street>283 First Avenue</street>
<city>Big City</city>
<state>MA</state>
<zip>02718</zip>
</address>
</addressbook>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="no"/>
<xsl:key name="zipcodes" match="address" use="zip"/>
<xsl:template match="/">
<table border="1">
<xsl:for-each select="//address[generate-id(.)=generate-id(key("zipcodes", zip)[1])]">
<xsl:sort select="zip"/>
<xsl:for-each select="key("zipcodes", zip)">
<xsl:sort select="name/last-name"/>
<xsl:sort select="name/first-name"/>
<tr>
<xsl:if test="position() = 1">
<td valign="center" bgcolor="#999999">
<xsl:attribute name="rowspan">
<xsl:value-of select="count(key("zipcodes", zip))"/>
</xsl:attribute>
<b>
<xsl:text>Zip code </xsl:text><xsl:value-of select="zip"/>
</b>
</td>
</xsl:if>
<td align="right">
<xsl:value-of select="name/first-name"/>
<xsl:text> </xsl:text>
<b><xsl:value-of select="name/last-name"/></b>
</td>
<td>
<xsl:value-of select="street"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="city"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="state"/>
<xsl:text> </xsl:text>
<xsl:value-of select="zip"/>
</td>
</tr>
</xsl:for-each>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
Output:
<table border="1"><tr><td valign="center" bgcolor="#999999" rowspan="1"><b>Zip code 00218</b></td><td align="right">Doris <b>Smith</b></td><td>707 New Way, New York, ME 00218</td></tr><tr><td valign="center" bgcolor="#999999" rowspan="1"><b>Zip code 02718</b></td><td align="right">Jane <b>Lee</b></td><td>283 First Avenue, Big City, MA 02718</td></tr></table>
for-each select=preceding-sibling::address[zip=./zip]
File: Data.xml
<?xml version="1.0"?>
<addressbook>
<address>
<name>
<title>Ms.</title>
<first-name>Doris</first-name>
<last-name>Smith</last-name>
</name>
<street>707 New Way</street>
<city>New York</city>
<state>ME</state>
<zip>00218</zip>
</address>
<address>
<name>
<title>Ms.</title>
<first-name>Jane</first-name>
<last-name>Lee</last-name>
</name>
<street>930-A Street</street>
<city>Twincity</city>
<state>MA</state>
<zip>02930</zip>
</address>
</addressbook>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no"/>
<xsl:variable name="newline">
<xsl:text></xsl:text>
</xsl:variable>
<xsl:template match="/">
<xsl:text>Addresses sorted by zip code</xsl:text>
<xsl:value-of select="$newline"/>
<xsl:for-each select="addressbook/address">
<xsl:sort select="zip"/>
<xsl:choose>
<xsl:when test="not(preceding-sibling::address[zip=./zip])">
<xsl:value-of select="$newline"/>
<xsl:text>Zip code </xsl:text>
<xsl:value-of select="zip"/>
<xsl:text> (</xsl:text>
<xsl:value-of select="city"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="state"/>
<xsl:text>): </xsl:text>
<xsl:value-of select="$newline"/>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="no">
<xsl:text>./zip=</xsl:text><xsl:value-of select="./zip"/><xsl:text>, </xsl:text>
<xsl:for-each select="preceding-sibling::address[zip=./zip]">
<xsl:text>preceding-sibling=</xsl:text><xsl:value-of select="name/first-name"/><xsl:text> </xsl:text><xsl:value-of select="name/last-name"/>
</xsl:for-each>
</xsl:message>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="name/title">
<xsl:value-of select="name/title"/>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:value-of select="name/first-name"/>
<xsl:text> </xsl:text>
<xsl:value-of select="name/last-name"/>
<xsl:value-of select="$newline"/>
<xsl:value-of select="street"/>
<xsl:value-of select="$newline"/>
<xsl:value-of select="$newline"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Output:
Addresses sorted by zip codeZip code 00218 (New York, ME): Ms. Doris Smith707 New WayMs. Jane Lee930-A Street
Nested for-each loop with sorting
File: Data.xml
<?xml version="1.0"?>
<addressbook>
<address>
<name>
<title>Ms.</title>
<first-name>Doris</first-name>
<last-name>Smith</last-name>
</name>
<street>707 New Way</street>
<city>New York</city>
<state>ME</state>
<zip>00218</zip>
</address>
</addressbook>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="newline">
<xsl:text></xsl:text>
</xsl:variable>
<xsl:template match="/">
<xsl:for-each select="addressbook/address">
<xsl:sort select="name/last-name"/>
<xsl:sort select="name/first-name"/>
<xsl:for-each select=".">
<xsl:if test="name/title">
<xsl:value-of select="name/title"/>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:value-of select="name/first-name"/>
<xsl:text> </xsl:text>
<xsl:value-of select="name/last-name"/>
<xsl:value-of select="$newline"/>
<xsl:value-of select="street"/>
<xsl:value-of select="$newline"/>
<xsl:value-of select="city"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="state"/>
<xsl:text> </xsl:text>
<xsl:value-of select="zip"/>
<xsl:value-of select="$newline"/>
<xsl:value-of select="$newline"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Output:
Ms. Doris Smith707 New WayNew York, ME 00218
Output xml elements in for-each loop
File: Data.xml
<?xml version="1.0"?>
<addressbook>
<address>
<name>
<title>Ms.</title>
<first-name>Doris</first-name>
<last-name>Smith</last-name>
</name>
<street>707 New Way</street>
<city>New York</city>
<state>ME</state>
<zip>00218</zip>
</address>
<address>
<name>
<title>Ms.</title>
<first-name>Jane</first-name>
<last-name>Lee</last-name>
</name>
<street>930-A Street</street>
<city>Twincity</city>
<state>MA</state>
<zip>02930</zip>
</address>
</addressbook>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="newline">
<xsl:text></xsl:text>
</xsl:variable>
<xsl:template match="/">
<addressbook>
<xsl:for-each select="addressbook/address">
<xsl:sort select="name/last-name"/>
<xsl:sort select="name/first-name"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</addressbook>
</xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?><addressbook><address><name><title>Ms.</title><first-name>Doris</first-name><last-name>Smith</last-name></name><street>707 New Way</street><city>New York</city><state>ME</state><zip>00218</zip></address><address><name><title>Ms.</title><first-name>Jane</first-name><last-name>Lee</last-name></name><street>930-A Street</street><city>Twincity</city><state>MA</state><zip>02930</zip></address></addressbook>
The xsl:for-each element allows all nodes in a node-set to be processed according to the XSLT instructions nested inside the xsl:for-each element.
Use for-each to output table row
File: Data.xml
<?xml version="1.0"?>
<results group="A">
<match>
<date>10-Jun-98</date>
<team score="2">team 1</team>
<team score="1">team 2</team>
</match>
<match>
<date>10-Jun-98</date>
<team score="2">team 3</team>
<team score="2">team 4</team>
</match>
<match>
<date>16-Jun-98</date>
<team score="1">team 2</team>
<team score="1">team 4</team>
</match>
</results>
File: Transform.xslt
<?xml version="1.0"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:variable name="league">
<xsl:apply-templates select="results" />
</xsl:variable>
<xsl:template match="/">
<html>
<head>
<title>League Table</title>
</head>
<body>
<h1>League Table</h1>
<table border="2" cellpadding="5">
<thead>
<td>Team</th>
<td>Played</th>
<td>Won</th>
<td>Lost</th>
<td>Drawn</th>
<td>For</th>
<td>Against</th>
</thead>
<tbody>
<xsl:for-each select="$league/league/team">
<tr>
<td>
<xsl:value-of select="@name" />
</td>
<td>
<xsl:value-of select="@played" />
</td>
<td>
<xsl:value-of select="@won" />
</td>
<td>
<xsl:value-of select="@lost" />
</td>
<td>
<xsl:value-of select="@drawn" />
</td>
<td>
<xsl:value-of select="@for" />
</td>
<td>
<xsl:value-of select="@against" />
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
</xsl:transform>
Output:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>League Table</title>
</head>
<body>
<h1>League Table</h1>
<table border="2" cellpadding="5">
<thead>
<td>Team</th>
<td>Played</th>
<td>Won</th>
<td>Lost</th>
<td>Drawn</th>
<td>For</th>
<td>Against</th>
</thead>
<tbody></tbody>
</table>
</body>
</html>
Use for-each loop to output list items
File: Data.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- tutorial.xml -->
<tutorial>
<section>
<title>Java</title>
<panel>
<title>Introduction</title>
<!-- ... -->
</panel>
<panel>
<title>Swing</title>
<!-- ... -->
</panel>
<panel>
<title>GUI</title>
<!-- ... -->
</panel>
<panel>
<title>2D animation</title>
<!-- ... -->
</panel>
</section>
</tutorial>
File: Transform.xslt
<?xml version="1.0" encoding="utf-8"?>
<!-- tutorial.xsl -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="tutorial">
<xsl:for-each select="section">
<h1>
<xsl:text>Section </xsl:text>
<xsl:value-of select="position()"/>
<xsl:text>. </xsl:text>
<xsl:value-of select="title"/>
</h1>
<ul>
<xsl:for-each select="panel">
<li>
<xsl:value-of select="position()"/>
<xsl:text>. </xsl:text>
<xsl:value-of select="title"/>
</li>
</xsl:for-each>
</ul>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Output:
<h1>Section 1. Java</h1>
<ul>
<li>1. Introduction</li>
<li>2. Swing</li>
<li>3. GUI</li>
<li>4. 2D animation</li>
</ul>
xsl:for-each instruction contains a template, which is applied to each node selected with select attribute.
File: Data.xml
<?xml version="1.0" encoding="utf-8"?>
<data>
<AAA id="a1" pos="start">
<BBB id="b1"/>
<BBB id="b2"/>
</AAA>
<AAA id="a2">
<BBB id="b3"/>
<BBB id="b4"/>
<CCC id="c1">
<DDD id="d1"/>
</CCC>
<BBB id="b5">
<CCC id="c2"/>
</BBB>
</AAA>
</data>
File: Transform.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="//BBB">
<DIV style="color:red">
<xsl:value-of select="name()"/>
<xsl:text> id=</xsl:text>
<xsl:value-of select="@id"/>
</DIV>
</xsl:for-each>
<xsl:for-each select="source/AAA/CCC">
<DIV style="color:navy">
<xsl:value-of select="name()"/>
<xsl:text> id=</xsl:text>
<xsl:value-of select="@id"/>
</DIV>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?><DIV style="color:red">BBB id=b1</DIV><DIV style="color:red">BBB id=b2</DIV><DIV style="color:red">BBB id=b3</DIV><DIV style="color:red">BBB id=b4</DIV><DIV style="color:red">BBB id=b5</DIV>