Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use for-each inside another for-each in xsl

Tags:

xml

xslt

the xml is

<XYZ>
    <manager>
      <mId>m1</mId>
      <mName>mName1</mName>
    <manager>
    <manager>
      <mId>m2</mId>
      <mName>mName2</mName>
    <manager>
    <department>
      <dName>d1</dName>
      <dManager>m1</dManager>
    <department>
    <department>
      <dName>d2</dName>
      <dManager>m1</dManager>
    <department>
    <department>
      <dName>d3</dName>
      <dManager>m2</dManager>
    <department>
</XYZ>          

for each manager, output all the department name he manages, my code is like

<xsl:for-each select="XYZ/manager">
<xsl:variable name='mId'>
  <xsl:value-of select="mId"/>
</xsl:variable>
<p>
  manager <xsl:value-of select="mName"/> manages department 
  <xsl:for-each select="XYZ/department[dManager=$mId]">
    <xsl:value-of select="XYZ/department/dName"/>,  

  </xsl:for-each>
</p>
</xsl:for-each>

and it outputs nothing after the manages department, anyone know what's wrong? thank you!

like image 703
user2810081 Avatar asked Nov 19 '14 06:11

user2810081


People also ask

How does <XSL for each> work?

The <xsl:for-each> element loops through each node in a specified node set. <!-- Content --> Required. An XPath expression that specifies which node set to be processed.

How to do looping in XSLT?

The <xsl:for-each> element allows you to do looping in XSLT. The XSL <xsl:for-each> element can be used to select every XML element of a specified node-set: Note: The value of the select attribute is an XPath expression. An XPath expression works like navigating a file system; where a forward slash (/) selects subdirectories.

What is the difference between XSL for each and XSL apply-templates?

The xsl:for-each element can be used as an alternative to xsl:apply-templates where the child nodes of the current node are known in advance. It may have one or more xsl:sort child elements to define the order of sorting.

What is XSLT for each in Python?

XSLT for each is defined as the iteration process that allows retrieving data from the specified nodes. Based on the selection criteria defined with these functions, it makes a loop through multiple nodes. This works in adding up with the function <xsl:value-of>. It repeats the block of content over each element in the given node-set.


2 Answers

You had a context problem inside your for-each : the for-each instruction changes the context, then when you apply your second for-each and/or when you call for the value of department/dName, you're not in the right context.

Then just fix your two last select as below :

<xsl:for-each select="XYZ/manager">
  <xsl:variable name='mId'>
     <xsl:value-of select="mId"/>
   </xsl:variable>
   <p>
     manager <xsl:value-of select="mName"/> manages department 
     <xsl:for-each select="/XYZ/department[dManager=$mId]">
       <xsl:value-of select="dName"/>,  
     </xsl:for-each>
   </p>
</xsl:for-each>
like image 52
Eric S Avatar answered Oct 17 '22 17:10

Eric S


This might help you. Have corrected your XPaths with little modification in output format:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="/">
    <xsl:for-each select="/XYZ/manager">
        <xsl:variable name='mId'>
            <xsl:value-of select="mId"/>
        </xsl:variable>manager <xsl:value-of select="mName"/> manages department <xsl:for-each select="/XYZ/department[dManager=$mId]">
            <xsl:value-of select="dName"/>
            <xsl:if test="position() != last()">, </xsl:if>
        </xsl:for-each>
        <xsl:if test="position() != last()">
            <xsl:text>&#x0A;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>
like image 39
Lingamurthy CS Avatar answered Oct 17 '22 16:10

Lingamurthy CS