XSLT apply templates select condition on node list

Viewed 19

I have an xml with a list and wanted to apply template on that which will send only specific nodes by a condition, but it is applying on the whole list. Could someone if I am missing anything, I am relatively new to XSL. The condition I wanted to apply is if dep is 7 and no city tag exists, I started with condition to check if dep is 7. After apply template if i print my list, it is getting all of them, Instead of dep just with value 7.In my output I expect not to have dep with value 9.

Input XML:

<employeeList>

  <employee>
    <dep>7</dep>
    <salary>900</salary>
  </employee>

  <employee>
    <dep>7</dep>
    <city>LA</city>
    <salary>500</salary>
  </employee>

  <employee>
    <dep>9</dep>
    <salary>600</salary>
  </employee>

  <employee>
    <dep>7</dep>
    <salary>800</salary>
  </employee>

</employeeList>

My XSL:

 <xsl:apply-templates select="employeeList[employee/dep = '7']" mode="e"/>

<xsl:template match="employeeList" mode="e">
       <xsl:for-each select="employee">
           <dep>
               <xsl:value-of select="dep" />
           </dep>
       </xsl:for-each>

Output XML:

<dep>7</dep><dep>7</dep><dep>9</dep><dep>7</dep>
2 Answers

The condition I wanted to apply is if dep is 7 and no city tag exists

Such condition can be easily implemented using e.g.:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/employeeList">
    <root>
        <xsl:for-each select="employee[dep='7' and not(city)]">
            <dep>7</dep>
        </xsl:for-each>
    </root>
</xsl:template>

</xsl:stylesheet>

Or shortly:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/employeeList">
    <root>
        <xsl:copy-of select="employee[dep='7' and not(city)]/dep"/>
    </root>
</xsl:template>

</xsl:stylesheet>

But it's hard to see the point in outputting X number of <dep>7</dep> elements.

You select the employeeList based on a condition on its employee/dep, but once you have selected it, that condition no longer matters, and the <xsl:for-each select="employee"> selects all employees, regardless of their dep.

You can repeat the condition in the xsl:for-each statement:

<xsl:for-each select="employee[dep = '7']">
Related