XML Mini Tutorial
XML Mini Tutorial
XML Mini-Tutorial
Michael I. Schwartzbach
Copyright © 2000 BRICS, University of Aarhus
http://www.brics.dk/~mis/ITU/XML/
What is XML?
HTML vs. XML
A conceptual view of XML
A concrete view of XML
Applications of XML
XML technologies
Namespaces
The recipe example
Schema languages
A schema for recipes
XLink, XPointer, and XPath
Pointing at recipes
XML-QL
Querying the recipes
XSLT
A style sheet for recipes
Exercises
Michael I. Schwartzbach
Copyright © 2000 BRICS, University of Aarhus
http://www.brics.dk/~mis/ITU/
These mini-tutorials are created as part of the course Internet Programming at the IT-University of
Copenhagen.
HTML (PDF)
JavaScript (PDF)
XML (PDF)
What is XML?
XML is a framework for defining markup languages:
● there is no fixed collection of markup tags;
<h1>Rhubarb Cobbler</h1>
<h2>[email protected]</h2>
<h3>Wed, 14 Jun 95</h3>
<table>
<tr><td> 2 1/2 cups <td> diced rhubarb (blanched with boiling
water, drain)
<tr><td> 2 tablespoons <td> sugar
<tr><td> 2 <td> fairly ripe bananas sliced 1/4" round
<tr><td> 1/4 teaspoon <td> cinnamon
<tr><td> dash of <td> nutmeg
</table>
<description>
Rhubarb Cobbler made with bananas as the main sweetener.
It was delicious.
</description>
<ingredients>
...
</ingredients>
<preparation>
Combine all and use as cobbler, pie, or crisp.
</preparation>
❍ a name, and
Often, comments and entity declarations are not explicitly represented in the tree.
process clear
Applications of XML
There are already hundreds of serious applications of XML.
XHTML
CML
<molecule id="METHANOL">
<atomArray>
<stringArray builtin="elementType">C O H H H H</stringArray>
<floatArray builtin="x3" units="pm">
-0.748 0.558 -1.293 -1.263 -0.699 0.716
</floatArray>
</atomArray>
</molecule>
WML
<?xml version="1.0"?>
<wml>
<card id="Card1" title="Wap-UK.com">
<p>
Hello World
</p>
</card>
</wml>
XML technologies
Just a notation for trees is not enough:
● the real force of XML is generic languages and tools!
Namespaces
Consider an XML language WidgetML which uses XHTML as a sublanguage for help messages:
<widget type="gadget">
<head size="medium"/>
<big><subwidget ref="gizmo"/></big>
<info>
<head>
<title>Description of gadget</title>
</head>
<body>
<h1>Gadget</h1>
A gadget contains a big gizmo
</body>
</info>
</widget>
● this complicates things for processors and might even cause ambiguities;
● farsbrød;
● hornfisk;
● islagkage;
● laksemousse;
● nougattoppe;
● rabarberdessert;
● smørrebrød.
We can represent this collection as an XML document.
Schema languages
The syntax of a new XML language must be formalized:
● this is similar to the formal syntax of a programming language;
A schema processor:
● checks that an application document satisfies the schema;
<ElementDef ID="beskrivelse">
<Content IDRef="hvadsomhelst"/>
</ElementDef>
<ContentDef ID="hvadsomhelst">
<ZeroOrMore>
<Union>
<StringType/><AnyElement/>
</Union>
</ZeroOrMore>
</ContentDef>
<ElementDef ID="titel">
<Content IDRef="hvadsomhelst"/>
</ElementDef>
<ElementDef ID="opskrift">
<AttributeDecl Name="kvantitet" Optional="no"/>
<AttributeDecl Name="tid" Optional="yes"/>
<Sequence>
<Element IDRef="titel"/>
<Content IDRef="indhold"/>
<Optional>
<Element Name="garniture">
<Content IDRef="hvadsomhelst"/>
</Element>
</Optional>
<Optional>
<Element Name="servering">
<Content IDRef="hvadsomhelst"/>
</Element>
</Optional>
<Optional>
<Element Name="tips">
<Content IDRef="hvadsomhelst"/>
</Element>
</Optional>
<Element Name="energi">
<AttributeDecl Name="kjoule" Optional="no"/>
<AttributeDecl Name="fedt" Optional="no">
<StringType IDRef="tal"/>
</AttributeDecl>
<AttributeDecl Name="kulhydrat" Optional="no">
<StringType IDRef="tal"/>
</AttributeDecl>
<AttributeDecl Name="protein" Optional="no">
<StringType IDRef="tal"/>
</AttributeDecl>
<AttributeDecl Name="alkohol" Optional="yes">
<StringType IDRef="tal"/>
</AttributeDecl>
</Element>
</Sequence>
</ElementDef>
<ContentDef ID="indhold">
<Sequence>
<OneOrMore>
<Element IDRef="ingrediens"/>
</OneOrMore>
<Element Name="tilberedning">
<Content IDRef="hvadsomhelst"/>
</Element>
</Sequence>
</ContentDef>
<ElementDef ID="ingrediens">
<AttributeDecl Name="navn" Optional="no"/>
<AttributeDecl Name="antal" Optional="yes">
<Union>
<String Value="*"/>
<StringType IDRef="tal"/>
</Union>
</AttributeDecl>
<AttributeDecl Name="enhed" Optional="yes"/>
<If><Attribute Name="antal"/>
<Then>
<Empty/>
</Then>
<Else>
<Not><Attribute Name="enhed"/></Not>
<Content IDRef="indhold"/>
</Else>
</If>
</ElementDef>
<StringTypeDef ID="cifre">
<OneOrMore>
<CharRange Start="0" End="9"/>
</OneOrMore>
</StringTypeDef>
<StringTypeDef ID="tal">
<Sequence>
<StringType IDRef="cifre"/>
<Optional>
<Sequence>
<String Value=","/>
<StringType IDRef="cifre"/>
</Sequence>
</Optional>
</Sequence>
</StringTypeDef>
</DSD>
Pointing at recipes
The following simple XPath expressions point to parts of the XML recipe document:
//ingrediens[@navn="radiser i små tern"]/@antal
200
//ingrediens[@antal="100" and @enhed="g"]/@navn
flødeost med løg og urter
blødt smør i mindre stykker
Feta ost 45+
smeltet overtrækschokolade
//titel[text()="Citrontærte"]
/following-sibling::ingrediens[@navn="dej"]/tilberedning/text()
Bland mel og sukker i en skål. Skær smørret i mindre stykker og
smuldr det i melblandingen, til den ligner revet ost. Tilsæt vand
og saml hurtigt dejen. Tryk den ud i en smurt springform (ca. 22 cm
i diameter). Lad dejen gå halvt op ad formens side. Stil den
tildækket i køleskabet i mindst 1 time. Forbag bunden midt i ovnen
i 12 minutter ved 200 grader.
XML-QL
XML-QL is a query language for XML documents:
● XML document can be seen as generalizations of database relations;
● XML-QL is a similar generalization of SQL;
● it can extract data from exisiting XML documents and construct new XML documents.
WHERE <opskriftsamling>
<opskrift>
<titel>$t</titel>
</opskrift>
</opskriftsamling>
IN "karoline.xml"
CONSTRUCT <titel>$t</titel>
<?xml version="1.0"?<
<XML>
<titel>Filokurve med tigerrejer</titel>
<titel>Laksemousse</titel>
<titel>Smørrebrød med flødeost og tomat</titel>
<titel>Citrontærte</titel>
<titel>Hornfisk med radisesalat</titel>
<titel>Islagkage med chokolade</titel>
<titel>Rabarberdessert med jordbær</titel>
<titel>Nougattoppe</titel>
<titel>Græsk farsbrød og agurkesalat</titel>
</XML>
CONSTRUCT <opskriftermedsukker> {
WHERE <opskriftsamling>
<opskrift>
<titel>$t</>
<ingrediens*>
<ingrediens navn="sukker"/>
</>
</opskift>
</opskriftsamling>
IN "karoline.xml"
CONSTRUCT <navn>$t</navn>
} </opskriftermedsukker>
<?xml version="1.0"?>
<opskriftermedsukker>
<navn>Citrontærte</navn>
<navn>Islagkage med chokolade</navn>
<navn>Rabarberdessert med jordbær</navn>
</opskriftermedsukker>
<?xml version="1.0"?>
<XML>
<ingrediens navn="æggeblommer">
<ret>Islagkage med chokolade</ret>
</ingrediens>
<ingrediens navn="friskpresset citronsaft">
<ret>Laksemousse</ret>
<ret>Citrontærte</ret>
</ingrediens>
<ingrediens navn="jordbær i skiver">
<ret>Rabarberdessert med jordbær</ret>
</ingrediens>
<ingrediens navn="dej">
<ret>Citrontærte</ret>
</ingrediens>
<ingrediens navn="agurketern">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="hornfisk">
<ret>Hornfisk med radisesalat</ret>
</ingrediens>
<ingrediens navn="yoghurt">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="kvarkdressing">
<ret>Hornfisk med radisesalat</ret>
</ingrediens>
<ingrediens navn="sukker">
<ret>Citrontærte</ret>
<ret>Rabarberdessert med jordbær</ret>
<ret>Islagkage med chokolade</ret>
</ingrediens>
<ingrediens navn="radisesalat">
<ret>Hornfisk med radisesalat</ret>
</ingrediens>
<ingrediens navn="mellemstore æg">
<ret>Citrontærte</ret>
</ingrediens>
<ingrediens navn="rom">
<ret>Islagkage med chokolade</ret>
</ingrediens>
<ingrediens navn="vand">
<ret>Rabarberdessert med jordbær</ret>
<ret>Græsk farsbrød og agurkesalat</ret>
<ret>Citrontærte</ret>
</ingrediens>
<ingrediens navn="koldt smør">
<ret>Citrontærte</ret>
</ingrediens>
<ingrediens navn="hvedemel">
<ret>Citrontærte</ret>
</ingrediens>
<ingrediens navn="små papir- eller folieforme">
<ret>Nougattoppe</ret>
</ingrediens>
<ingrediens navn="fyld">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="fars">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="friskkværnet peber">
<ret>Laksemousse</ret>
<ret>Græsk farsbrød og agurkesalat</ret>
<ret>Hornfisk med radisesalat</ret>
</ingrediens>
<ingrediens navn="rabarber">
<ret>Rabarberdessert med jordbær</ret>
</ingrediens>
<ingrediens navn="agurkesalat">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="bladselleri">
<ret>Laksemousse</ret>
</ingrediens>
<ingrediens navn="knust fed hvidløg">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="piskefløde">
<ret>Nougattoppe</ret>
<ret>Islagkage med chokolade</ret>
<ret>Laksemousse</ret>
</ingrediens>
<ingrediens navn="frisk, hakket persille">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="groft salt">
<ret>Laksemousse</ret>
<ret>Græsk farsbrød og agurkesalat</ret>
<ret>Filokurve med tigerrejer</ret>
<ret>Hornfisk med radisesalat</ret>
</ingrediens>
<ingrediens navn="husblas">
<ret>Laksemousse</ret>
</ingrediens>
<ingrediens navn="Feta ost 45+">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="frisk, rød chilipeber">
<ret>Filokurve med tigerrejer</ret>
</ingrediens>
<ingrediens navn="tørret basilikum">
<ret>Smørrebrød med flødeost og tomat</ret>
</ingrediens>
<ingrediens navn="lille hakket zittauerløg">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="smør">
<ret>Filokurve med tigerrejer</ret>
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="hakket hvidløgsfed">
<ret>Filokurve med tigerrejer</ret>
</ingrediens>
<ingrediens navn="creme fraiche">
<ret>Filokurve med tigerrejer</ret>
<ret>Laksemousse</ret>
</ingrediens>
<ingrediens navn="overtræk">
<ret>Islagkage med chokolade</ret>
</ingrediens>
<ingrediens navn="parfait">
</ingrediens>
<ingrediens navn="mælk">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="groft knækbrød">
<ret>Smørrebrød med flødeost og tomat</ret>
</ingrediens>
<ingrediens navn="hakket lammekød">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="friske citronmelisseblade">
<ret>Citrontærte</ret>
</ingrediens>
<ingrediens navn="ris">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="frossen, optøet filodej">
<ret>Filokurve med tigerrejer</ret>
</ingrediens>
<ingrediens navn="citroncreme">
<ret>Citrontærte</ret>
</ingrediens>
<ingrediens navn="mellemstort æg">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="smeltet smør">
<ret>Filokurve med tigerrejer</ret>
</ingrediens>
<ingrediens navn="majsstivelse">
<ret>Citrontærte</ret>
</ingrediens>
<ingrediens navn="parboiled ris">
<ret>Græsk farsbrød og agurkesalat</ret>
</ingrediens>
<ingrediens navn="blødt smør i mindre stykker">
<ret>Citrontærte</ret>
</ingrediens>
<ingrediens navn="iskold piskefløde">
<ret>Rabarberdessert med jordbær</ret>
</ingrediens>
<ingrediens navn="rababerkompot">
<ret>Rabarberdessert med jordbær</ret>
</ingrediens>
<ingrediens navn="jordbær">
<ret>Rabarberdessert med jordbær</ret>
</ingrediens>
<ingrediens navn="filokurve">
<ret>Filokurve med tigerrejer</ret>
</ingrediens>
XSLT
An XSLT style sheets transforms an XML document into another:
● if the target language is XHTML, then this is similar to a CSS style sheet;
However, the following service correctly processes an XML document with an associated stylesheet
(given a full URL):
http://www.brics.dk/~mis/ITU/XML/karoline.xml process clear
<xsl:template match="opskriftsamling">
<html>
<head>
<title><xsl:apply-templates select="beskrivelse"/></title>
</head>
<body>
<xsl:apply-templates select="opskrift"/>
</body>
</html>
</xsl:template>
<xsl:template match="beskrivelse">
<xsl:value-of select="text()"/>
</xsl:template>
<xsl:template match="opskrift">
<h1>
<xsl:value-of select="titel"/><xsl:text> </xsl:text>
(<xsl:value-of select="@kvantitet"/>)
</h1>
<ul>
<xsl:apply-templates select="ingrediens"/>
<xsl:apply-templates select="tilberedning"/>
</ul>
<xsl:apply-templates select="garniture"/>
<xsl:apply-templates select="servering"/>
<xsl:apply-templates select="tips"/>
<xsl:apply-templates select="energi"/>
<hr/>
</xsl:template>
<xsl:template match="ingrediens">
<xsl:choose>
<xsl:when test="@antal">
<li>
<xsl:if test="@antal!='*'">
<xsl:value-of select="@antal"/>
<xsl:text> </xsl:text>
<xsl:value-of select="@enhed"/>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:value-of select="@navn"/>
</li>
</xsl:when>
<xsl:otherwise>
<li><xsl:value-of select="@navn"/></li>
<ul>
<xsl:apply-templates select="ingrediens"/>
<xsl:apply-templates select="tilberedning"/>
</ul>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="tilberedning">
<xsl:if test="node() or text()">
<li>
<i>
<xsl:value-of select="text()|node()"/>
</i>
</li>
</xsl:if>
</xsl:template>
<xsl:template match="garniture">
<h3>Garniture</h3>
<xsl:value-of select="text()|node()"/>
</xsl:template>
<xsl:template match="servering">
<h3>Servering</h3>
<xsl:value-of select="text()|node()"/>
</xsl:template>
<xsl:template match="tips">
<h3>Tips</h3>
<xsl:value-of select="text()|node()"/>
</xsl:template>
<xsl:template match="energi">
<p/>
<table border="2">
<tr>
<th>kJoule</th><th>Fedt</th><th>Kulhydrat</th><th>Protein</th>
<xsl:if test="@alkohol">
<th>Alkohol</th>
</xsl:if>
</tr>
<tr>
<td align="right"><xsl:value-of select="@kjoule"/></td>
<td align="right"><xsl:value-of select="@fedt"/>%</td>
<td align="right"><xsl:value-of select="@kulhydrat"/>%</td>
<td align="right"><xsl:value-of select="@protein"/>%</td>
<xsl:if test="@alkohol">
<td align="right"><xsl:value-of select="@alkohol"/>%</td>
</xsl:if>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
Exercises
1. Browse through the collection of XML applications.
2. Add the recipe for tigerrejer to the XML recipe collection (save as file). Check that the result is well-formed XML.
3. Apply the given style sheet to this extended collection.
4. Add the necessary HTML to the following style sheet:
<xsl:template match="opskriftsamling">
<html>
<xsl:apply-templates select="opskrift"/>
</html>
</xsl:template>
<xsl:template match="opskrift">
<xsl:value-of select="titel"/>
<xsl:value-of select="energi/@kjoule"/>
<xsl:value-of select="energi/@fedt"/>
<xsl:value-of select="energi/@kulhydrat"/>
<xsl:value-of select="energi/@protein"/>
<xsl:if test="energi/@alkohol">
<xsl:value-of select="energi/@alkohol"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
which extracts nutrition tables from recipe collections. Try it out. As it stands, the output looks like: