XML Tutorial/XSLT stylesheet/for each — различия между версиями

Материал из Web эксперт
Перейти к: навигация, поиск
 
м (1 версия)
 
(нет различий)

Текущая версия на 11:26, 26 мая 2010

compares sorted and unsorted xsl:for-each element

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="utf-8"?>

   <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>

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="//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>
Position</TH>
         <td>Last</TH>
         <td>Name</TH>
<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"?>
Position</TH>
         <td>Last</TH>
         <td>Name</TH>
<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>
Position</TH><td>Last</TH><td>Name</TH>
<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></source>


for-each select="addressbook/address" and sort

   <source lang="xml">

File: Data.xml <?xml version="1.0"?>

<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"?>

<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></source>


for-each select=//address[generate-id(.)=generate-id(key(zipcodes, zip)[1])]

   <source lang="xml">

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="/">
Position</TH><td>Last</TH><td>Name</TH>
<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"/> <xsl:if test="position() = 1"> </xsl:if> </xsl:for-each> </xsl:for-each>
               <xsl:attribute name="rowspan">
                 <xsl:value-of select="count(key("zipcodes", zip))"/>
               </xsl:attribute>
               
                 <xsl:text>Zip code </xsl:text><xsl:value-of select="zip"/>
               
             <xsl:value-of select="name/first-name"/>
             <xsl:text> </xsl:text>
             <xsl:value-of select="name/last-name"/>
             <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"/>
 </xsl:template>

</xsl:stylesheet> Output:

Zip code 00218Doris Smith707 New Way, New York, ME 00218
Zip code 02718Jane Lee283 First Avenue, Big City, MA 02718
</source>


for-each select=preceding-sibling::address[zip=./zip]

   <source lang="xml">

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</source>


Nested for-each loop with sorting

   <source lang="xml">

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</source>


Output xml elements in for-each loop

   <source lang="xml">

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></source>


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.

   <source lang="xml">

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>

League Table

<thead> <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>

League Table

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" />
<thead>
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></source>


Use for-each loop to output list items

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="utf-8"?>

<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"?>

<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">

<xsl:text>Section </xsl:text> <xsl:value-of select="position()"/> <xsl:text>. </xsl:text> <xsl:value-of select="title"/>

    <xsl:for-each select="panel">
  • <xsl:value-of select="position()"/> <xsl:text>. </xsl:text> <xsl:value-of select="title"/>
  •        </xsl:for-each>
    
   </xsl:for-each>
 </xsl:template>

</xsl:stylesheet> Output:

Section 1. Java

  • 1. Introduction
  • 2. Swing
  • 3. GUI
  • 4. 2D animation
</source>


xsl:for-each instruction contains a template, which is applied to each node selected with select attribute.

   <source lang="xml">

File: Data.xml <?xml version="1.0" encoding="utf-8"?>

   <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>

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">
         <xsl:value-of select="name()"/>
         <xsl:text> id=</xsl:text>
         <xsl:value-of select="@id"/>
     </xsl:for-each>
     <xsl:for-each select="source/AAA/CCC">
         <xsl:value-of select="name()"/>
         <xsl:text> id=</xsl:text>
         <xsl:value-of select="@id"/>
     </xsl:for-each>
   </xsl:template>

</xsl:stylesheet> Output:

<?xml version="1.0" encoding="UTF-8"?>
BBB id=b1
BBB id=b2
BBB id=b3
BBB id=b4
BBB id=b5
</source>