Reputation: 167
I have the following xml file:
<root>
<sub type="print">print</sub>
<sub type="email">email</sub>
</root>
I want to match each type up against the following list:
<types>
<type>email</type>
<type>broadcast</type>
<type>mobile</type>
<type>print</type>
<type>web</type>
</types>
Using this xslt with the "doc" being the xml and "types" the list above passed in as parameters:
<xsl:stylesheet
xmlns = "http://www.w3.org/1999/xhtml"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="xhtml" indent="yes" />
<xsl:param name="doc"/>
<xsl:param name="types"/>
<xsl:template match="/">
<xsl:for-each select="$doc//sub">
<xsl:variable name="count">
<xsl:number value="position()" format="1"/>
</xsl:variable>
<ul>
<xsl:for-each select="$types//type">
<xsl:choose>
<xsl:when test="$doc//sub[$count]/@type = text()">
<li>
<b>
<xsl:value-of select="$doc//sub[$count]/@type"/> - <xsl:value-of select="text()"/>
</b>
</li>
</xsl:when>
<xsl:otherwise>
<li>
<xsl:value-of select="$doc//sub[$count]/@type"/> - <xsl:value-of select="text()"/>
</li>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</ul>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
This should give me an unordered list for each sub in my xml printing the type from the sub and then each type. When the sub and the type match, it should be bold. I want this:
<ul>
<li>print - email</li>
<li>print - broadcast</li>
<li>print - mobile</li>
<li><b>print - print</b></li>
<li>print - web</li>
</ul>
<ul>
<li><b>email - email</b></li>
<li>email - broadcast</li>
<li>email - mobile</li>
<li>email - print</li>
<li>email - web</li>
</ul>
But I get this:
<ul>
<li><b>print email - email</b></li>
<li>print email - broadcast</li>
<li>print email - mobile</li>
<li><b>print email - print</b></li>
<li>print email - web</li>
</ul>
<ul>
<li><b>print email - email</b></li>
<li>print email - broadcast</li>
<li>print email - mobile</li>
<li><b>print email - print</b></li>
<li>print email - web</li>
</ul>
Thanks for any and all help.
Upvotes: 2
Views: 562
Reputation: 5652
Given your sub file as main input and the types in subtypes.xml
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="sub">
<ul>
<xsl:apply-templates select="doc('subtypes.xml')">
<xsl:with-param name="this" select="." tunnel="yes"/>
</xsl:apply-templates>
</ul>
</xsl:template>
<xsl:template match="type">
<xsl:param name="this" tunnel="yes"/>
<li>
<xsl:choose>
<xsl:when test="$this/@type=.">
<b><xsl:value-of select="$this/@type,' - ',."/></b>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$this/@type,' - ',."/>
</xsl:otherwise>
</xsl:choose>
</li>
</xsl:template>
</xsl:stylesheet>
produces:
<?xml version="1.0" encoding="UTF-8"?>
<ul>
<li>print - email</li>
<li>print - broadcast</li>
<li>print - mobile</li>
<li><b>print - print</b></li>
<li>print - web</li>
</ul>
<ul>
<li><b>email - email</b></li>
<li>email - broadcast</li>
<li>email - mobile</li>
<li>email - print</li>
<li>email - web</li>
</ul>
Upvotes: 0
Reputation: 52888
I think it might have something to do with the multiple uses of //
.
Try replacing your root template (match="/"
) with this:
<xsl:template match="/">
<html>
<xsl:for-each select="$doc/root/sub">
<xsl:variable name="vType" select="@type"/>
<ul>
<xsl:for-each select="$types/types/type">
<li>
<xsl:choose>
<xsl:when test=".=$vType">
<b>
<xsl:value-of select="concat($vType,' - ',.)"/>
</b>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($vType,' - ',.)"/>
</xsl:otherwise>
</xsl:choose>
</li>
</xsl:for-each>
</ul>
</xsl:for-each>
</html>
</xsl:template>
NOTE: I added the <html>
tag to keep my output well-formed when testing.
Upvotes: 1