XMLXSLProgramkodenxsl:apply-templates
[ Hem ] Allmänt ASP XML SQL ADO HTML CSS VB Java Design Karta
Grunderna XSL Dynamiska sidor XML i praktiken

xsl:apply-templates

xsl:apply-templates

Om vi skriver program i ett "normalt" programmeringsspråk blir det fort en ruskig "spagettikod" om man inte använder subrutiner (Sub och Function för VB programmerare - riktiga programmerare har bara function). Motsvarande gäller även för XSL. Man måste få någon form av subrutiner för att strukturera koden.

Nedan kommer ett exempel på apply-templates.

XML filen:

xml24_2.xml

<?xml version="1.0" encoding="iso-8859-1"?> 
<?xml-stylesheet type="text/xsl" href="xml24_2.xsl"?>
<!DOCTYPE racers [
   <!ELEMENT racers (driver*) >
   <!ELEMENT driver (name, nationality,description?) >
   <!ATTLIST driver type (F1 | rally) #REQUIRED>
   <!ELEMENT name (#PCDATA) >
   <!ELEMENT nationality (#PCDATA) >
   <!ELEMENT description (#PCDATA) >
]>

<racers>
   <driver type="F1">
     <name>Mika Häkkinen</name>
     <nationality>Finn</nationality>
     <description>
       Tvåfaldig värlsdmästare och
       pappa till Hugo. Bättre än Schumi!
     </description>
   </driver>
   <driver type="rally">
     <name>Marcus Grönholm</name>
     <nationality>Finn</nationality>
     <description>Finlandssvensk</description>
   </driver>
   <driver type="rally">
     <name>Colin McRae</name>
     <nationality />
     <description>Pratar en ruskig dialekt</description>
   </driver>
   <driver type="F1">
     <name>David Coulthard</name>
     <nationality>Scottish</nationality>
   </driver>
</racers>
Öppna XML filen   Öppna XML konverterad till HTML (Även NS)

XSL filen

xml24_2.xsl

<?xml version='1.0' encoding="iso-8859-1" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
<html>
   <head>
     <title>Racing</title>
     <style type="text/css">
       h4 {font-family:verdana,arial,sans-serif; color:#666666;}
     </style>
   </head>
   <body bgcolor="#FFFFFF" text="#000000">
     <h4>Förare</h4>
     <table cellspacing="0" cellpadding="1" bgcolor="#0000FF"><tr><td>
     <table cellspacing="0" bgcolor="#FFFFFF">

     <tr bgcolor="#EEEEEE">
       <td>Namn</td>
       <td> Nationalitet</td>
       <td>Kommentarer</td>
     </tr>
     <!--  loopa genom alla förare. Sortera efter namn -->
     <xsl:for-each select="racers/driver" order-by="name">
       <tr>
         <!--  kör apply-templates -->
         <xsl:apply-templates />
       </tr>
     </xsl:for-each>
     </table>
     </td></tr></table>
   </body>
</html>
</xsl:template>

<!--  template som används för name taggarna -->
<xsl:template match="name">
   <td valign="top">
   <xsl:if test=".[.='Marcus Grönholm']">
     <!--  sätt bgcolor för Bosses tabellcell -->
     <xsl:attribute name="bgcolor">#FFFFcc</xsl:attribute>
   </xsl:if>
   <xsl:value-of select="."/></td>
</xsl:template>

<!--  template som används för nationality taggarna -->
<xsl:template match="nationality">
   <td valign="top"><xsl:value-of select="."/></td>
</xsl:template>

<!--  template som används för description taggarna -->
<xsl:template match="description">
   <td valign="top"><i><xsl:value-of select="."/></i></td>
</xsl:template>
</xsl:stylesheet>
Om du har IE 5.0 eller nyare kan du klicka här för att se filen i praktiken

Detta fungerar så att man kör apply-templates "i blindo". XSL kommer då att titta på vilken tagg (nod) som gäller för tillfället. Om noden är <name> kör tolken den template som finns för name. Om noden är <nationality> körs en annan template.

Vid första anblicken verkar detta inte så impunerande men tänk igenom hur det skulle se ut i ett "vanligt" programmeringsspråk. Något i den här stilen skulle behövas:

If typeOf node is name Then
   doName
elseIf TypeOf node is description then
   doDescription
Else
   doNationality
End If

Programlogiken i XSL är snarare:

Här har du någonting. Se efter om det finns någonting att göra av det, tack.

Man kan även specificera vilken template som skall matchas genom att sätta select="pattern" i apply-templates satsen.

Mer avancerat exempel på apply-templates

Nedan har jag ett exempel. För att göra livet lite mer spännande har jag använt en rekursiv XML fil som då även kräver en rekursiv XSL.

xml24_1.xml

<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="xml24_1.xsl"?>
<!DOCTYPE xmlcourse [

    <!ELEMENT xmlcourse ( chapter* )>
    <!ELEMENT chapter ( title* , chapter* )>
    <!ELEMENT title ( #PCDATA )>
]>
<!--  observera det rekursiva datat -->
<!-- 
   en begränsning som jag satt in för att göra
   det lättare är att title alltid måste komma före chapter
-->

<xmlcourse>
   <chapter>
     <title>1. Grunderna</title>
     <chapter>
       <title>1.1. Intro till XML</title>
       <chapter>
         <title>1.1.1. Filens konstruktion</title>
         <title>1.1.2. Validering av filen</title>
         <chapter>
           <title>1.1.2.1. Well-formed</title>
           <title>1.1.2.2. DTD</title>
         </chapter>
       </chapter>
     </chapter>
     <chapter>
       <title>1.2. XSL</title>
       <title>1.3. Xpath</title>
       <title>1.4. XTransformations</title>
       <title>1.5. Xrated</title>
     </chapter>
   </chapter>
   <chapter>
     <title>2.DOM</title>
     <chapter>
       <title>2.1. DOM Benedictini</title>
       <title>2.2. DOM de Louise</title>
       <title>2.3. DOM andra</title>
       <title>2.4. DOM Dummaste</title>
     </chapter>
   </chapter>
</xmlcourse>
Öppna XML filen   Öppna XML konverterad till HTML (Även NS)

xml24_1.xsl

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">


<!--  vi skapar en template för rotnoden -->
<xsl:template match="/">
   <!--  helt ordinär html kod -->
   <html>
   <head>
   <title>TEST</title>
   </head>
   <body>
   <!--  loopa genom huvudkapitlen -->
   <xsl:for-each select="xmlcourse/chapter">
     <!--  sätt in dem i en unordered (ul) html lista -->
     <ul>
       <!--  sätt in en rad med title -->
       <li><xsl:value-of select="title" /></li>
       <!--  se om det finns nån lämplig template -->
       <xsl:apply-templates />
     </ul>
   </xsl:for-each>
   </body>
   </html>
</xsl:template>


<!--  denna template används för chapter noder -->
<xsl:template match="chapter">
   <!--  sätt in en ny ul -->
   <ul>
   <!--  loopa sen genom alla titlar -->
   <xsl:for-each select="title">
     <li><xsl:value-of select="." /></li>
   </xsl:for-each>

   <!--  och åberopa templaten på nytt för chapters -->
   <xsl:apply-templates />
   </ul>
</xsl:template>

</xsl:stylesheet>

Om du har IE 5.0 eller nyare kan du klicka här för att se filen i praktiken

 

  xsl:for-eachXSL Övningar
XSL
XSL i praktiken
XSL loopar
XSL programmering
XSL patterns
Patterns exempel
Programkoden
xsl:if
xsl:choose
xsl:for-each
xsl:apply-templates
XSL Övningar
XML versioner
Microsofts lösning
Nummer och datum
Typexempel för XSL ...


Top
< xsl:for-each XSL Övningar>
© Anders Enges, Vörå 2002  | 09.10.01 11:08 Visa asp koden