Reputation: 21
Playing around with xml and xslt, and trying to get the hang of it.
My xml code looks like this:
<hello-world>
<header eng="Welcome!" dk="Velkommen"></header>
<greeting>
<eng>Hello, World!</eng>
<dk>Hej verden</dk>
</greeting>
<greeting>
<eng>Hello space</eng>
<dk>Hej Rummet!</dk>
</greeting>
<greeting>
<eng>Hey Mom! Im coding XSLT</eng>
<dk>Hej Mor! Jeg koder XSLT</dk>
</greeting>
</hello-world>
So far I've translated my xml to this html:
<html>
<body>
<div>
<ul>
<li>Hello, World!</li>
</ul>
</div>
<div>
<ul>
<li>Hello space</li>
</ul>
</div>
<div>
<ul>
<li>Hey Mom! Im coding XSLT</li>
</ul>
</div>
<div>
<ul>
<li>Hej verden</li>
</ul>
</div>
<div>
<ul>
<li>Hej Rummet!</li>
</ul>
</div>
<div>
<ul>
<li>Hej Mor! Jeg koder XSLT</li>
</ul>
</div>
</body>
</html>
With the use of this xslt:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="/hello-world/greeting">
<div>
<ul>
<li><xsl:value-of select="eng" /></li>
</ul>
</div>
</xsl:for-each>
<xsl:for-each select="/hello-world/greeting">
<div>
<ul>
<li><xsl:value-of select="dk" /></li>
</ul>
</div>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
What I would like to know, if there is a better way to do this, and how I could implement and select the correct attribute on the header and apply in the foreach.
Thanks!
Upvotes: 1
Views: 128
Reputation: 7820
In XSLT you can define your own templates using the apply-template function which is somewhat the equivalent to a function in a procedural programming language. The template is applied to the selection value. Templates are a mighty concept. They can also accept parameters, so that you can pass more than one value to the template and control the flow.
You need to define the templates for the two languages (after the main template):
<xsl:template match="dk">
<div>
<ul>
<li>
<xsl:value-of select="." />
</li>
</ul>
</div>
</xsl:template>
<xsl:template match="eng">
<div>
<ul>
<li>
<xsl:value-of select="." />
</li>
</ul>
</div>
</xsl:template>
and then call them in the main template for the wanted value:
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="/hello-world/greeting">
<xsl:apply-templates select="eng"></xsl:apply-templates>
</xsl:for-each>
<xsl:for-each select="/hello-world/greeting">
<xsl:apply-templates select="dk"></xsl:apply-templates>
</xsl:for-each>
</body>
</html>
</xsl:template>
The output will be the same as your original. You are basically saying something like formatOutputFor(currentStringValue)
. The complete transformation looks like this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="/hello-world/greeting">
<xsl:apply-templates select="eng"></xsl:apply-templates>
</xsl:for-each>
<xsl:for-each select="/hello-world/greeting">
<xsl:apply-templates select="dk"></xsl:apply-templates>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template match="dk">
<div>
<ul>
<li>
<xsl:value-of select="." />
</li>
</ul>
</div>
</xsl:template>
<xsl:template match="eng">
<div>
<ul>
<li>
<xsl:value-of select="." />
</li>
</ul>
</div>
</xsl:template>
</xsl:stylesheet>
Upvotes: -1
Reputation: 5432
You can use a template that does something for both "eng" and "dk" elements, and apply it in sequence for "eng" and "dk":
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="hello-world/greeting/eng"/>
<xsl:apply-templates select="hello-world/greeting/dk"/>
</body>
</html>
</xsl:template>
<xsl:template match="dk | eng">
<div>
<ul>
<li><xsl:value-of select="."/></li>
</ul>
</div>
</xsl:template>
</xsl:stylesheet>
Upvotes: 2