Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old August 24th, 2009, 09:28 PM
Authorized User
 
Join Date: Aug 2009
Posts: 31
Thanks: 16
Thanked 1 Time in 1 Post
Default nested for-each of different nodes

Hi,

I've been looking for a way to do nested for-each of different nodes but I'm not successful yet. I've read somewhere that I need to use templates but I don't know how to do it in XSL

I just want my data to be displayed horizontally. I would be forever grateful for any help.

<records>
<plan planid="XXXX">

<field>
<fieldId>DateCreated</fieldId>
<fieldtext>Creation Date</fieldtext>
<fieldvalue>12-Mar-2009</fieldvalue>
</field>
<field>
<fieldId>PlanName</fieldId>
<fieldtext>Name of Plan</fieldtext>
<fieldvalue>Health Care</fieldvalue>
</field>
</plan>

<plan planid="YYYY">

<field>
<fieldId>DateCreated</fieldId>
<fieldtext>Creation Date</fieldtext>
<fieldvalue>14-Mar-2009</fieldvalue>
</field>
<field>
<fieldId>PlanName</fieldId>
<fieldtext>Name of Plan</fieldtext>
<fieldvalue>Death Accident</fieldvalue>
</field>
</plan>
</records>

I want my data to be displayed like this:

------------ XXXX YYYY
Creation Date: 12-Mar-2009 14-Mar-2009
Name of Plan: Health Care Death Accident
 
Old August 25th, 2009, 04:26 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Actually this is the kind of situation where template rules are least useful: generally "pull" processing (for-each) works better where the logic is defined by the output structure, "push" processing (apply-templates) where it is dictated by the input.

Your input has a lot of redundancy, for example field[1]/fieldtext has the same value for every plan. Let's assume you can trust this to be regular.

Assuming you are generating HTML, you want something like this (with <records> as the context item):

Code:
<xsl:variable name="r" select="."/>
<table>
  <tr>
     <td></td>
     <xsl:for-each select="plan">
         <td><xsl:value-of select="@planid"/></td>
     </
  </
  <xsl:for-each select="plan[1]/field">
     <xsl:variable name="p" select="position()"/>
     <tr>
         <td><xsl:value-of select="fieldtext"/></td>
          <xsl:for-each select="$r/plan">
               <td><xsl:value-of select="field[$p]/fieldvalue"/></td>
          </
     </
  </
</table>
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
The Following User Says Thank You to mhkay For This Useful Post:
kokoness (August 25th, 2009)
 
Old August 25th, 2009, 07:03 AM
Authorized User
 
Join Date: Aug 2009
Posts: 31
Thanks: 16
Thanked 1 Time in 1 Post
Talking re: nested for-each of different nodes

Hi Sir Michael,

Thank you very much for the reply. Your reply is appreciated very much. You rock! Your code looks great.

I tried the code, however I'm not getting any content for the transformation. I don't know what's wrong.

HCFAS106.xml
Code:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="HCFAS106.xsl"?>
<records>
	<plan planid="XXXX">
		<field>
			<fieldId>DateCreated</fieldId>
			<fieldtext>Creation Date</fieldtext>
			<fieldvalue>12-Mar-2009</fieldvalue>
		</field>
		<field>
			<fieldId>PlanName</fieldId>
			<fieldtext>Name of Plan</fieldtext>
			<fieldvalue>Health Care</fieldvalue>
		</field>
	</plan>
	<plan planid="YYYY">
		<field>
			<fieldId>DateCreated</fieldId>
			<fieldtext>Creation Date</fieldtext>
			<fieldvalue>14-Mar-2009</fieldvalue>
		</field>
		<field>
			<fieldId>PlanName</fieldId>
			<fieldtext>Name of Plan</fieldtext>
			<fieldvalue>Death Accident</fieldvalue>
		</field>
	</plan>
</records>
HCFAS106.xsl
Code:
<?xml version="1.0"?>
<html xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:version="1.0">
	<head><title>Test</title></head>
	<body>
		<xsl:variable name="r" select="."/>
		<table>
			  <tr>
				<td></td>
				<xsl:for-each select="plan">
					<td><xsl:value-of select="@planid"/></td>
				</xsl:for-each>
			  </tr>
			  <xsl:for-each select="plan[1]/field">
				<xsl:variable name="p" select="position()"/>
				<tr>
					<td><xsl:value-of select="fieldtext"/></td>
					<xsl:for-each select="$r/plan">
						<td><xsl:value-of select="field[$p]/fieldvalue"/></td>
					</xsl:for-each>
				</tr>
			</xsl:for-each>
		</table>
	</body>
</html>
Regards,
Jan
 
Old August 25th, 2009, 07:12 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

If you want to write your stylesheet in that form of a single literal result element then you need to change your paths:
Code:
<html xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:version="1.0">
    <head><title>Test</title></head>
    <body>
        <xsl:variable name="r" select="records"/>
        <table>
              <tr>
                <td></td>
                <xsl:for-each select="records/plan">
                    <td><xsl:value-of select="@planid"/></td>
                </xsl:for-each>
              </tr>
              <xsl:for-each select="records/plan[1]/field">
                <xsl:variable name="p" select="position()"/>
                <tr>
                    <td><xsl:value-of select="fieldtext"/></td>
                    <xsl:for-each select="$r/plan">
                        <td><xsl:value-of select="field[$p]/fieldvalue"/></td>
                    </xsl:for-each>
                </tr>
            </xsl:for-each>
        </table>
    </body>
</html>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
The Following User Says Thank You to Martin Honnen For This Useful Post:
kokoness (August 25th, 2009)
 
Old August 25th, 2009, 07:23 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

I was careful to state when writing the code that it expected the context item to be the <records> element. You can set that to the context item by enclosing the code in <xsl:for-each select="records">, or you can change the paths to assume a different context node.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
The Following User Says Thank You to mhkay For This Useful Post:
kokoness (August 25th, 2009)
 
Old August 25th, 2009, 09:22 AM
Authorized User
 
Join Date: Aug 2009
Posts: 31
Thanks: 16
Thanked 1 Time in 1 Post
Cool re: nested for-each of different nodes

Thanks a lot again Sir Michael. I'm still starting to learn XSLT. I thought that the "." would automatically point to the first node which is "records"

I still have a lot to learn. You made my week very bright

More power to you and to the other guys here. Thank you for your never ending support to those in need of solutions. You'll never really know how much it means to us.

Your XSLT 2.0 book will be on top of my xsl to buy.

My thanks goes to Sir Martin as well





Similar Threads
Thread Thread Starter Forum Replies Last Post
How to get the value of last 3 nested nodes using xsl:for-each rabs XSLT 3 February 26th, 2009 10:17 AM
How to get the value of first 3 nested nodes using xsl:for-each eruditionist XSLT 5 February 25th, 2009 04:18 PM
How to value in b/n nodes Swetha XSLT 1 May 20th, 2008 12:20 PM
help with nodes/children bmmayer XML 0 July 13th, 2007 05:04 PM
How to select these nodes? hustsay23 XSLT 1 September 7th, 2006 04:15 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.