webForumDet fria alternativet

Inte så haj på xslt

XML

2 svar · 378 visningar · startad av hanna

Medlem sedan jan. 200262 inlägg
Frågan#1

xml struktur:

månad
vecka
dag
dag
dag...
/vecka
vecka
dag
dag
dag...
/vecka
/månad

Jag vill lista ut i tabell med

- Månad
- Vecka
- Dagar
- Vecka
- Dagar

Hur skriver jag då? Jag får alla dagar för hela månaden under varje vecka

Medlem sedan juli 20013 378 inlägg
#2

Hmmm...
Här kommer ett exempel på hur du kan göra baserat på ett gammalt kalenderexempel jag hade liggande.
Strukturen liknar din, men jag använder kalender-år-månad-vecka-dag som struktur (tänket verkar dock
vara väldigt lika ;) )
Exempeldata:

<?xml version="1.0" encoding="ISO-8859-1"?>
<kalender>
<år anno="2002">
<månad namn="Maj" nummer="5">
   <vecka nummer="18">
      <dag datum="1" dag="3">första</dag>
      <dag datum="2" dag="4">andra</dag>
      <dag datum="3" dag="5">tredje</dag>
      <dag datum="4" dag="6">fjärde</dag>
      <dag datum="5" dag="7">femte</dag>
   </vecka>
   <vecka nummer="19">
      <dag datum="6" dag="1">sjätte</dag>
      <dag datum="7" dag="2">sjunde</dag>
      <dag datum="8" dag="3">åttonde</dag>
      <dag datum="9" dag="4">nionde</dag>
      <dag datum="10" dag="5">tionde</dag>
      <dag datum="11" dag="6">elfte</dag>
      <dag datum="12" dag="7">tolfte</dag>
   </vecka>
   <vecka nummer="20">
      <dag datum="13" dag="1">trettonde</dag>
      <dag datum="14" dag="2">fjortonde</dag>
      <dag datum="15" dag="3">femtonde</dag>
      <dag datum="16" dag="4">sextonde</dag>
      <dag datum="17" dag="5">sjuttonde</dag>
      <dag datum="18" dag="6">artonde</dag>
      <dag datum="19" dag="7">nittonde</dag>
   </vecka>
   <vecka nummer="21">
      <dag datum="20" dag="1">tjugonde</dag>
      <dag datum="21" dag="2">tjugoförsta</dag>
      <dag datum="22" dag="3">tjugoandra</dag>
      <dag datum="23" dag="4">tjugotredje</dag>
      <dag datum="24" dag="5">tjugofjärde</dag>
      <dag datum="25" dag="6">tjugofemte</dag>
      <dag datum="26" dag="7">tjugosjätte</dag>
   </vecka>
   <vecka nummer="22">
      <dag datum="27" dag="1">tjugosjunde</dag>
      <dag datum="28" dag="2">tjugoåttonde</dag>
      <dag datum="29" dag="3">tjugonionde</dag>
      <dag datum="30" dag="4">trettionde</dag>
      <dag datum="31" dag="5">trettiförsta</dag>
   </vecka>
</månad>
<månad namn="Juni" nummer="6">
   <vecka nummer="22">
      <dag datum="1" dag="6">Jippi!</dag>
      <dag datum="2" dag="7">Sommarlov!!!!</dag>
   </vecka>
</månad>
</år>
</kalender>

När man gör en XSLT-fil, är det ofta lättast om man tänker i "svarta lådor", och angriper en nivå åt gången.
I detta fall kan man t.ex. börja med att skapa en mall som matchar mot rot-elementet i indatat (kalender) och som lägger ut en grundstruktur för en HTML-sida när den träffar på det.

Jag vill alltså skapa en kalender som innehåller information från alla <år> som kan hittas:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "html" encoding="ISO-8859-1" />

<xsl:template match="/kalender">	
<html>
<head><title>Kalender</title></head>
<body>
	<xsl:apply-templates select="år" />
</body>
</html>
</xsl:template>
...
...
...
</xsl:stylesheet>

Punkterna markerar var jag sedan lägger in följande regler.
Observera att jag alltså inte använder en "generell" <xsl:apply-templates />, utan väljer att specificera att det är just bara mallen för <år>-taggar jag vill använda här! - detta för att dels undvika att jag längre fram skjuter mig i foten genom att döpa någon mall fel, och dels för att jag senare då ganska enkelt kan lägga till sortering av informationen om det skulle visa sig nödvändigt.

Nästa steg blir att skapa regeln för ett år. Jag väljer att lägga året i en egen tabell, och att lägga ut en överskrift med årtalet före tabellen. (kom ihåg att den här regeln anropas en gång för varje <år> tack vare användningen av <xsl:apply-templates select="år" />, så man kan tack och lov begränsa sig till att tänka på bara ett år åt gången här !!

<xsl:template match="år">	
	<h1><xsl:value-of select="@anno"/></h1>
	<table border="1">
		<xsl:apply-templates select="månad" />
	</table>
</xsl:template>

Ok. Dags att ta sig an en månad på samma sätt.
In med en tabellrad som ger månaden en överskrift, och matcha sedan alla <vecka> som finns i den här månaden:

<xsl:template match="månad">	
	<tr>
		<th colspan="3" bgcolor="black" style="color:white" align="left">
			<xsl:value-of select="@namn"/>
		</th>
	</tr>
	<xsl:apply-templates select="vecka" />
</xsl:template>

Nästa steg är veckan, Regeln för en <vecka> skall bara hantera de dagar som finns i veckan:

<xsl:template match="vecka">	
	<tr>
		<th colspan="3" bgcolor="gray" align="left">
			Vecka <xsl:value-of select="@nummer"/>
		</th>
	</tr>
	<xsl:apply-templates select="dag" />
</xsl:template>

Och till sist är det dagens tur, och här kommer till sist förklaringen till varför jag kör med colspan="3" ovan - Jag plockar ut tre tabellceller med information om varje <dag>:

<xsl:template match="dag">	
	<tr>
		<xsl:if test="@dag=6">
			<xsl:attribute name="bgcolor">silver</xsl:attribute>
		</xsl:if>	
		<xsl:if test="@dag=7">
			<xsl:attribute name="bgcolor">silver</xsl:attribute>
		</xsl:if>	
		<td>
<xsl:choose>
	<xsl:when test="@dag=1">Måndag</xsl:when>
	<xsl:when test="@dag=2">Tisdag</xsl:when>
	<xsl:when test="@dag=3">Onsdag</xsl:when>
	<xsl:when test="@dag=4">Torsdag</xsl:when>
	<xsl:when test="@dag=5">Fredag</xsl:when>
	<xsl:when test="@dag=6">Lördag</xsl:when>
	<xsl:otherwise>Söndag</xsl:otherwise>
</xsl:choose>
		</td>
		<td>
			<xsl:value-of select="@datum"/>
		</td>
		<td>
			<xsl:value-of select="."/>
		</td>
</tr>
</xsl:template>

Sådär!

Tricket är alltså att inte försöka skriva alla utmatchningar av taggar i grund-regeln, utan att i stället succesivt skapa regler för taggarna längre ner i strukturen och på så sätt låta apply-templates med select="..." göra grovjobbet åt en.

Exemplen ligger på http://jarvklo.net/xmlexempel/kalender.xml och
http://jarvklo.net/xmlexempel/kalender.xsl

Medlem sedan jan. 200262 inlägg
#3

Tack så mycket för din hjälp.
Skall prova detta.

265 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
129 ms — deklarationer (db)
0 ms — hämta statistik (cache)
133 ms — hämta tråd, inlägg och bilagor (db)
125 ms — ändringar (db)