Task 3: More XSLT templates
XSLT templates
Let's transform more complex XML now:
<?xml version="1.0" encoding="UTF-8"?> <shelf> <book> <title>Starting with XSLT</title> <author>P2PU collaboration</author> </book> <cd> <title>Some music</title> <artist>Various</artist> </cd> <book> <title>XSLT mindtricks for experts</title> <author>Yoda</author> </book> </shelf>
In this XML (which represents a shelf) we have two books and one CD.
XSL matching templates
For example we want to get all book titles. Below is one of various solutions to get the book titles out of the above XML. When programming (XSLT is programming) there is often more than one solution to getting the expected result. So maybe when you are an advanced XSLT programmer you will think that my solution below can also be made in a shorter way.
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" > <xsl:output method="xml" encoding="UTF-8" indent="yes"/> <xsl:template match="/"> <allbooktitles> <xsl:apply-templates select="shelf"/> </allbooktitles> </xsl:template> <xsl:template match="shelf"> <xsl:apply-templates select="book"/> </xsl:template> <xsl:template match="book"> <xsl:apply-templates select="title"/> </xsl:template> <xsl:template match="title"> <booktitle> <xsl:value-of select="."/> </booktitle> </xsl:template> </xsl:stylesheet>
Please run a XSL transformation of the shelf.xml and the above transformation with:
xsltproc transform.xsl shelf.xml
the result will be:
<?xml version="1.0" encoding="UTF-8"?> <allbooktitles> <booktitle>Starting with XSLT</booktitle> <booktitle>XSLT mindtricks for experts</booktitle> </allbooktitles>
So what does our transformation do? It goes through the DOM tree of shelf.xml and it applies all matching templates to each level of the tree.
With <xsl:apply-templates select=”xxxxx”/> all matching templates which are a child of our current position in the XML will be processed.
So let's show this visually from the root node (← the invisble first node in every XML):
/ create (and output) an <allbooktitles> tag and then apply all templates which match <shelf> . We have only one document node named shelf. So let's go one level deeper inside the <shelf> tag:
/shelf apply all templates which match <book>. This matches to two book tags. As you can see we ignore CDs right now.
/shelf/book apply all templates which match title
/shelf/book/title create a <booktitle> tag and select the value of our current tag. The current tag, which is title at this moment is named with a special character “.” (a dot)
As you can see we layaway through the XML tree and apply matching templates.
Task for you:
Make a resulting XML with XSLT which displays all titles from books and CDs. While doing this keep sure to use only one matching “title” template.