Reputation: 1652
I have a xml file
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="main.xsl"?>
<document>
<parents>
<parent>
<name>Jordan</name>
<age>25</age>
<childs>
<child eyes="black">
<name>Ema</name>
</child>
<child eyes="blue">
<name>Kaloyan</name>
</child>
</childs>
</parent>
</parents>
</document>
which I want to filter with xsl file main.xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:include href="child.xsl" />
<xsl:template match="/">
<html>
<head>
<title>Head first</title>
</head>
<body>
<table border="1">
<xsl:for-each select="document/parents/parent">
<tr>
<td>
<xsl:text disable-output-escaping="yes">Name</xsl:text>
</td>
<td>
<xsl:value-of select="name"></xsl:value-of>
</td>
</tr>
<tr>
<td>
<xsl:text disable-output-escaping="yes">Age</xsl:text>
</td>
<td>
<xsl:value-of select="age"></xsl:value-of>
</td>
</tr>
<xsl:for-each select="childs/child">
<xsl:variable name="obj" select="."></xsl:variable>
<xsl:apply-templates select="//child[@eyes = 'black']" mode="child">
<xsl:with-param name="obj" select="$obj"></xsl:with-param>
</xsl:apply-templates>
</xsl:for-each>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
pointing to the child.xsl file:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="child">
<xsl:param name="obj"></xsl:param>
<h3><xsl:text disable-output-escaping="yes">Child name</xsl:text> </h3>
<h4><xsl:value-of select="$obj/name"></xsl:value-of></h4>
</xsl:template>
</xsl:stylesheet>
The required result is to see only one child name which is Ema but I see Ema twice:
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<title>Head first</title>
</head>
<body>
<table border="1">
<tbody>
<tr>
<td>Name</td>
<td>Jordan</td>
</tr>
<tr>
<td>Age</td>
<td>25</td>
</tr>
Ema Ema
</tbody>
</table>
</body>
</html>
Does anyone know why this is happening?
Upvotes: 1
Views: 90
Reputation: 29022
The reason is you are iterating over childs/child
with <xsl:for-each>
and there are two <child>
elements. Therefore <xsl:apply-templates select="//child[@eyes = 'black']" mode="child">
is executed two times and you get two Ema
s.
Upvotes: 1