Yordan Borisov
Yordan Borisov

Reputation: 1652

Filtering xml with xslt not working

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

Answers (1)

zx485
zx485

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 Emas.

Upvotes: 1

Related Questions