CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Dec 2004
    Posts
    35

    [Very simple newbiequestion] Selecting childnodes with foreach and apply templates.

    I have an XML which looks like this:

    <dvdcollection>
    <dvd id="1">
    <title>Text</title>
    <releasedate>Text</releasedate>
    <runningtime>Text</runningtime>
    <rating>Text</rating>
    <actors>
    <actor>Text</actor>
    <actor>Text</actor>
    <actor>Text</actor>
    </actors>
    </dvd>
    </dvdcollection>

    I'm presenting the data in a simple html-table with XSLT and want to print all the actors in one <td> with <br /> after each i use this XSLT:

    <xsl:template match="actors">
    <xsl:for-each select=".">
    <xsl:value-of select="actor"/><br />
    </xsl:for-each>
    </xsl:template>

    and in a for-each loop I use <td><xsl:apply-templates select="actors"/></td> as the tutorial on apply-templates on w3schools shows. I can display the title and other elements by just using <xsl:value-of select="title"/> but with this code I only get the first <actor> element in the tree.

    What am I missing?

    Ive tried having two foreach loops inside eachother but that didn't work and I've heard apply-templates is better in many ways. Please help.

  2. #2
    Join Date
    May 2003
    Location
    Denmark
    Posts
    1,315

    Re: [Very simple newbiequestion] Selecting childnodes with foreach and apply template

    Code:
    <xsl:for-each select=".">
    "." selects the current node, so you are running a for-each on the set of nodes that contains only the current node. But the current node is just one node, and it's already the current node, so the for-each does exactly nothing and might as well be removed.

    Code:
    <xsl:value-of select="actor"/>
    At the point you have this line actors is the current node, so "actor" selects all three actor elements. But value-of is a only accepts a single node, so it just uses the first of the three selected nodes.

    Better would be to replace the for-each with an apply-templates on the actor elements

    Code:
    <xsl:apply-templates select="actor"/>
    And make a template for actor
    Code:
    <xsl:template match="actor">
      <xsl:value-of select="text()"/>
      <br/>
    </xsl:template>
    Last edited by khp; December 22nd, 2004 at 10:32 PM.
    The biggest problem encountered while trying to design a system that was completely foolproof,
    was, that people tended to underestimate the ingenuity of complete fools.
    Douglas Adams

  3. #3
    Join Date
    Dec 2004
    Posts
    35

    Re: [Very simple newbiequestion] Selecting childnodes with foreach and apply template

    Thanks for clearing that up. My finished xsl looks like this and works like a charm.

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="html"/>

    <xsl:template match="/">
    <html>
    <body style="font-family: Arial; font-size: 0.9em">

    <h2>Andreas DVD-samling</h2>

    <table border="0" cellspacing="0" cellpadding="3">

    <tr style="background: black; color: white; text-align: left;">
    <th>Titel</th>
    <th>Utgivningsår</th>
    <th>Speltid</th>
    <th>Betyg</th>
    <th>Skådespelare</th>
    <th>Omslag</th>
    </tr>

    <xsl:for-each select="dvdcollection/dvd">
    <xsl:sort select="runningtime" data-type="number" order="descending" />
    <xsl:choose>
    <xsl:when test="position() mod 2 = 1">
    <tr style="background: white; color: black;">
    </xsl:when>
    <xsl:otherwise>
    <tr style="background: gray; color: white;">
    </xsl:otherwise>
    </xsl:choose>
    <td><xsl:value-of select="title"/></td>
    <td><xsl:value-of select="releasedate"/><xsl:if test="releasedate &gt; 2000">**</xsl:if></td>
    <td><xsl:value-of select="runningtime"/></td>
    <td><xsl:value-of select="rating"/><xsl:if test="rating = 5">*</xsl:if></td>
    <td><xsl:for-each select="actors"><xsl:apply-templates select="actor"/></xsl:for-each></td>
    <xsl:variable name="pos" select="concat(@id, '.jpg')" />
    <td><img src="images/{$pos}" /></td>
    </tr>
    </xsl:for-each>

    <tr style="background: black; color: white; text-align: right;">
    <th colspan="6">Snittbetyg <xsl:value-of select="sum(dvdcollection/dvd/rating) div count(dvdcollection/dvd/rating)"/></th>
    </tr>

    </table>

    <p>Det finns <xsl:value-of select="count(dvdcollection/dvd)"/> filmer i listan</p>
    <p>* Högsta betyg ** Släppt efter 2000</p>

    </body>
    </html>
    </xsl:template>

    <xsl:template match="actor">
    <xsl:value-of select="text()"/><br/>
    </xsl:template>

    </xsl:stylesheet>
    Last edited by LiquidShadows; December 23rd, 2004 at 10:07 AM.

  4. #4
    Join Date
    Feb 2005
    Posts
    2

    Post Re: [Very simple newbiequestion] Selecting childnodes with foreach and apply templates.

    Hi ..

    I have the following problem regarding childnodes and xsl:for-each select

    My XML looks like this :
    Code:
    <DATA>
    	<CASE>
    		<INSTRUCTION Type="Deleted">
    			<OPERATION>Blah blah</OPERATION>
    			<FEEDBACK>feedback1</FEEDBACK>
    			<FEEDBACK>feedback2</FEEDBACK>
    			<FEEDBACK>feedback3</FEEDBACK>
    			<FEEDBACK>feedback4</FEEDBACK>
    			<FEEDBACK>feedback5</FEEDBACK>
    			<TIME>time blah bah</TIME>
    		</INSTRUCTION>
    		<INSTRUCTION Type="Stable">
    			<OPERATION>Blah blah</OPERATION>
    			<FEEDBACK>feedback1</FEEDBACK>
    			<FEEDBACK>feedback2</FEEDBACK>
    			<FEEDBACK>feedback3</FEEDBACK>
    			<FEEDBACK>feedback4</FEEDBACK>
    			<FEEDBACK>feedback5</FEEDBACK>
    			<TIME>time blah bah</TIME>
    		</INSTRUCTION>
    		<INSTRUCTION Type="Modified">
    			<OPERATION>Blah blah</OPERATION>
    			<FEEDBACK>feedback1</FEEDBACK>
    			<FEEDBACK>feedback2</FEEDBACK>
    			<FEEDBACK>feedback3</FEEDBACK>
    			<FEEDBACK>feedback4</FEEDBACK>
    			<FEEDBACK>feedback5</FEEDBACK>
    			<TIME>time blah bah</TIME>
    		</INSTRUCTION>
    	</CASE>
    </DATA>
    And I basically want to use XSLT to represent this data in X-HTML format.

    Code:
    <xsl:for-each select="Instruction[@Type !='Stable']">
    <xsl:choose>
    <xsl:when test="@Type = 'Deleted'">
      <tr>
        <td class="delete_l">
          Instruction <xsl:value-of select="@Type"/>
        </td>	
        <td class="delete_r">
          <br/>
        </td>	
      </tr>
      <tr>
        <td class="delete_l">
          <br/>
        </td>	
        <td class="delete_r">
          <xsl:for-each select=".">
            <xsl:value-of select="."/>
          </xsl:for-each>
        </td>	
      </tr>
    </xsl:when>
    <xsl:otherwise>
      <tr>
        <td>
          Instruction <xsl:value-of select="@Type"/>
        </td>
        <td>
          <xsl:value-of select="@Type"/>
        </td>
      </tr>
    </xsl:otherwise>
    </xsl:choose>
    </xsl:for-each>
    The output is the nodes Operation+Feedback+Time in a cell, which i really do not understand.
    I actually want the results to come out one by one, and each node in one cell..
    Or at least being able to put a line break between them

    Can someone help me along with this please ??

  5. #5
    Join Date
    Feb 2005
    Posts
    2

    Re: [Very simple newbiequestion] Selecting childnodes with foreach and apply templates.

    Sorry for taking up your time. I just found out that I could use a couple of templates in series

    I'm kindly asking the admin to remove my post please ...

    Thanks a lot and sorry again ...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured