Tema:
Nedan är en XML fil som innnehåller relationer. Ett land har en
huvudstad samt städer. En stad har en location (land), där den finns.
Detta uttrycks med hjälp av id, idref och idrefs. Läs igenom XML filen
ordentligt innan du ser på resultatet...
xml_ex_2.xml
<?xml version="1.0" encoding="iso-8859-1" ?>
<?xml-stylesheet type="text/xsl" href="xml_ex_2.xsl"?>
<!DOCTYPE geography [
<!ELEMENT geography (country|city)*>
<!ELEMENT country (country_name, capital, cities)>
<!ELEMENT country_name (#PCDATA)>
<!ELEMENT capital EMPTY>
<!ELEMENT cities EMPTY>
<!ELEMENT city (city_name,location)>
<!ELEMENT city_name (#PCDATA)>
<!ELEMENT location EMPTY>
<!ATTLIST country country_id ID #REQUIRED>
<!ATTLIST capital capital_ref IDREF #REQUIRED>
<!ATTLIST cities city_refs IDREFS #IMPLIED>
<!ATTLIST city city_id ID #REQUIRED
type (city|parish) #IMPLIED>
<!ATTLIST location location_ref IDREF #REQUIRED>
]>
<geography>
<!-- ett land med ID="FIN" -->
<country country_id="FIN">
<!-- namnet på landet -->
<country_name>Finland</country_name>
<!-- huvudstaden - referens till en city nod -->
<capital capital_ref="HEL" />
<!-- övriga städer -referenser till city noder -->
<cities city_refs="VORA VASA" />
</country>
<country country_id="SVE">
<country_name>Sverige</country_name>
<capital capital_ref="STO" />
<cities city_refs="MAL UME" />
</country>
<country country_id="USA">
<country_name>Nordamerika</country_name>
<capital capital_ref="WAS" />
<cities city_refs="ANA NYC" />
</country>
<!-- en stad med ID="HEL" -->
<city city_id="HEL">
<!-- stadens namn -->
<city_name>Helsingfors</city_name>
<!-- var finns staden - referens till ett land -->
<location location_ref="FIN" />
</city>
<city city_id="VORA" type="parish">
<!-- kanske inte en stad, men... -->
<city_name>Vörå</city_name>
<location location_ref="FIN" />
</city>
<city city_id="VASA">
<city_name>Vasa</city_name>
<location location_ref="FIN" />
</city>
<city city_id="STO">
<city_name>Stockholm</city_name>
<location location_ref="SVE" />
</city>
<city city_id="MAL">
<city_name>Malmö</city_name>
<location location_ref="SVE" />
</city>
<city city_id="UME">
<city_name>Umeå</city_name>
<location location_ref="SVE" />
</city>
<city city_id="WAS">
<city_name>Washington</city_name>
<location location_ref="USA" />
</city>
<city city_id="ANA">
<city_name>Annapolis</city_name>
<location location_ref="USA" />
</city>
<city city_id="NYC">
<city_name>New York</city_name>
<location location_ref="USA" />
</city>
</geography>
Öppna XML filen Öppna XML konverterad till HTML (Även NS)
xml_ex_2.xsl
<?xml version='1.0' encoding="iso-8859-1" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<!-- matcha roten -->
<xsl:template match="/">
<!-- vanlig html -->
<html>
<head>
<title>IDREFS mm.</title>
<style>
<!-- lite uppsnyggning -->
body {
font-family:verdana,arial,sans-serif;
color:#666666;
}
h4 {
font-family:verdana,arial,sans-serif;
color:#666666;
font-size:24pt;
}
</style>
</head>
<body bgcolor="#F3F3F3" text="#000000">
<h4>Länder</h4>
<!-- loopa genom länderna - sortera enligt namn -->
<xsl:for-each select="geography/country" order-by="country_name">
<!-- visa landets namn -->
Land: <xsl:value-of select="country_name" /><br />
<!--
visa huvudstaden - detta sker genom en
referens till en city nod
-->
Huvudstad:
<xsl:value-of select="id(capital/@capital_ref)/city_name" />
<br />
<!--
visa övriga städer - referenser till city noder
-->
Städer:
<xsl:for-each select="id(cities/@city_refs)" >
<!--
eftersom vi skall visa städer på flera
ställen i denna fil så är det enklast
att skapa en template som används
. kommer att vara en city nod
-->
<xsl:apply-templates select="." />
</xsl:for-each>
<!-- enlinje på sidan -->
<hr size="1" color="#0000FF" />
</xsl:for-each>
<h4>Städer</h4>
<!-- loopa genom städerna - sortera omvänt enligt namn -->
<xsl:for-each select="geography/city" order-by="-city_name">
<xsl:choose>
<!-- är det en kommun ? -->
<xsl:when test="@type[ .= 'parish']">
Kommunen
</xsl:when>
<!-- om inte så var det en stad -->
<xsl:otherwise>
Staden
</xsl:otherwise>
</xsl:choose>
<!-- använd den färdiga templaten för städer -->
<xsl:apply-templates select="." />
finns i
<!-- kolla upp landet genom location referensen -->
<xsl:value-of select="id(location/@location_ref)/country_name" />
<hr size="1" color="#0000FF" />
</xsl:for-each>
</body>
</html>
</xsl:template>
<!-- rotens template slut -->
<!-- template för city noder -->
<xsl:template match="city">
<span>
<!-- lite hemkär får man väl vara - gissa var jag bor ;-) -->
<xsl:if test="@city_id[ .= 'VORA']">
<xsl:attribute name="style">
color:#FFFFCC;
font-weight:bold;
background-color:#000000;
</xsl:attribute>
</xsl:if>
<!-- visa stadens / kommunens namn -->
<xsl:value-of select="city_name" /></span>
</xsl:template>
<!-- city templaten slut -->
</xsl:stylesheet>
Om du har IE 5.0 eller nyare kan du klicka här för att se filen i praktiken
Lägg märke till konstruktionen id(capital/@capital_ref)/city_name
som fungerar på följande sätt:
Eftersom vi loopar på nivån geography/country kommer capital
att betyda geography/country/capital . För denna nod använder
vi id() metoden för att få mer data. id(capital/@capital_ref)
kommer att resultera i den city nod som hänvisas till. Denna nod
har en undernod med namnet city_name och dess värde vill vi ha.
Det fanns bara en huvudstad per land, men flera städer. Om vi använder
IDREFS skall dessa värden separeras med mellanslag i referensen. Eftersom
det är fråga om en lista kan vi använda xsl:for-each för
att loopa genom alla referenser. Raden <xsl:for-each select="id(cities/@city_refs)"
> kommer då att ge som resultat de city noder som relaterast till
i t.ex. <cities city_refs="MAL UME"/>
Detta är potent kod! Efter första chocken blir man närmast imponerad
över hur enkelt det är...
Kompatibilitet
Nedan är samma sak, fast med nyare XSL standarden:
Om du har IE 5.0 eller nyare kan du klicka här för att se filen
Öppna XML filen Öppna XML konverterad till HTML (Även NS)
Det är nog en hemsk soppa med de olika standarderna