Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > XML > XSLT
Password Reminder
Register
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
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 tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old October 18th, 2008, 10:15 PM
Registered User
 
Join Date: Oct 2008
Location: , , .
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default Help needed on XSLT

Hi,
I am new to XSLT programming. I have a VB application using XML & XSLT to generate email formats. I am struck with an issue:

<DatabaseData>

<RecordSet>

<Record MgrName="Ramakrishna Prasad" Email="baruprasad@yahoo.com" ID="1326" ArtName="PSPM" ResourceName="Nic" ResourceHrs="28" FunctionName="Other" Hours="28" SortOrder="991" PrjHrs="81.5"/>

<Record MgrName="Ramakrishna Prasad" Email="baruprasad@yahoo.com" ID="1326" ArtName="PSPM" ResourceName="Ravi" ResourceHrs="18" FunctionName="Project Management" Hours="16" SortOrder="1" PrjHrs="81.5"/>

<Record MgrName="Ramakrishna Prasad" Email="baruprasad@yahoo.com" ID="1326" ArtName="PSPM" ResourceName="Ravi" ResourceHrs="18" FunctionName="Support" Hours="1.5" SortOrder="990" PrjHrs="81.5"/>

<Record MgrName="Ramakrishna Prasad" Email="baruprasad@yahoo.com" ID="1326" ArtName="PSPM" ResourceName="Ravi" ResourceHrs="18" FunctionName="Time Off" Hours="0.5" SortOrder="992" PrjHrs="81.5"/>

<Record MgrName="Ramakrishna Prasad" Email="baruprasad@yahoo.com" ID="1326" ArtName="PSPM" ResourceName="Dean" ResourceHrs="20" FunctionName="Support" Hours="20" SortOrder="990" PrjHrs="81.5"/>

<Record MgrName="Ramakrishna Prasad" Email="baruprasad@yahoo.com" ID="1326" ArtName="PSPM" ResourceName="Ryan C Saul" ResourceHrs="4.5" FunctionName="Support" Hours="4.5" SortOrder="990" PrjHrs="81.5"/>

<Record MgrName="Ramakrishna Prasad" Email="baruprasad@yahoo.com" ID="1332" ArtName="Title" ResourceName="Marg" ResourceHrs="11" FunctionName="Project Management" Hours="8" SortOrder="1" PrjHrs="81.5"/>

<Record MgrName="Ramakrishna Prasad" Email="baruprasad@yahoo.com" ID="1332" ArtName="Title" ResourceName="Marg" ResourceHrs="11" FunctionName="Support" Hours="2" SortOrder="990" PrjHrs="81.5"/>

<Record MgrName="Ramakrishna Prasad" Email="baruprasad@yahoo.com" ID="1332" ArtName="Title" ResourceName="Marg" ResourceHrs="11" FunctionName="Time Off" Hours="1" SortOrder="992" PrjHrs="81.5"/>

<Record MgrName="Ram" Email="baruprasad@hotmail.com" ID="1326" ArtName="PSPM" ResourceName="Nic" ResourceHrs="28" FunctionName="Other" Hours="28" SortOrder="991" PrjHrs="81.5"/>

<Record MgrName="Ram" Email="baruprasad@hotmail.com" ID="1326" ArtName="PSPM" ResourceName="Ravi" ResourceHrs="18" FunctionName="Project Management" Hours="16" SortOrder="1" PrjHrs="81.5"/>

<Record MgrName="Ram" Email="baruprasad@hotmail.com" ID="1326" ArtName="PSPM" ResourceName="Ravi" ResourceHrs="18" FunctionName="Support" Hours="1.5" SortOrder="990" PrjHrs="81.5"/>

<Record MgrName="Ram" Email="baruprasad@hotmail.com" ID="1326" ArtName="PSPM" ResourceName="Ravi" ResourceHrs="18" FunctionName="Time Off" Hours="0.5" SortOrder="992" PrjHrs="81.5"/>

<Record MgrName="Ram" Email="baruprasad@hotmail.com" ID="1326" ArtName="PSPM" ResourceName="Dean" ResourceHrs="20" FunctionName="Support" Hours="20" SortOrder="990" PrjHrs="81.5"/>

<Record MgrName="Ram" Email="baruprasad@hotmail.com" ID="1326" ArtName="PSPM" ResourceName="Ryan C Saul" ResourceHrs="4.5" FunctionName="Support" Hours="4.5" SortOrder="990" PrjHrs="81.5"/>

<Record MgrName="Ram" Email="baruprasad@hotmail.com" ID="1332" ArtName="Title" ResourceName="Marg" ResourceHrs="11" FunctionName="Project Management" Hours="8" SortOrder="1" PrjHrs="81.5"/>

<Record MgrName="Ram" Email="baruprasad@hotmail.com" ID="1332" ArtName="Title" ResourceName="Marg" ResourceHrs="11" FunctionName="Support" Hours="2" SortOrder="990" PrjHrs="81.5"/>

<Record MgrName="Ram" Email="baruprasad@hotmail.com" ID="1332" ArtName="Title" ResourceName="Marg" ResourceHrs="11" FunctionName="Time Off" Hours="1" SortOrder="992" PrjHrs="81.5"/>

</RecordSet>

</DatabaseData>


and need to generate Email to each manager in the following format:

Manager : ramakrishna Prasad

****************************

ID:Name Resource Function Hrs

Total Hours 59.00

1326:PSPM
            Nic 28

                    Other 28

            Ravi 18

                    Project Management 16

                    Support 1.5

                    Time Off 0.5

1332:Title

            Marg 11

                    Project Management 8

                    Support 2

                    Time Off 1



Manager : ram

*************

Total Hours 59.00

1326:PSPM
            Nic 28

                    Other 28

            Ravi 18

                    Project Management 16

                    Support 1.5

                    Time Off 0.5

1332:Title

            Marg 11

                    Project Management 8

                    Support 2

                    Time Off 1


I tried in numberways to generate in the above format and not successful. The issue is, as the same project & resource data exists for two mangers, when I am trying to display "Functions" for second manager, its getting filtered.

Any help in this regard is appreciated.

Thanks
Ramakrishna



Baru
Reply With Quote
  #2 (permalink)  
Old October 19th, 2008, 11:38 AM
Friend of Wrox
Points: 6,676, Level: 34
Points: 6,676, Level: 34 Points: 6,676, Level: 34 Points: 6,676, Level: 34
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Nov 2007
Location: Germany
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Do you want to create HTML or plain text output with your XSLT stylesheet? If you want to produce HTML then please post the HTML markup, if you want to create plain text then I am afraid what you inserted in your first post is not clear, other than that you want to group by the MgrName attribute of the Record element. But it is not clear what data you want to extract for each MgrName as your sample result is not well formatted.
To group data with XSLT 1.0 look into Muenchian grouping as described here:
http://www.jenitennison.com/xslt/grouping/index.xml


--
  Martin Honnen
  Microsoft MVP - XML
Reply With Quote
  #3 (permalink)  
Old October 19th, 2008, 05:00 PM
mhkay's Avatar
Wrox Author
Points: 18,487, Level: 59
Points: 18,487, Level: 59 Points: 18,487, Level: 59 Points: 18,487, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

This is a standard grouping problem. Look up "grouping" in your favourite Wrox XSLT textbook for the solution.

Grouping is very easy in XSLT 2.0 using the new xsl:for-each-group instruction. It's rather harder in XSLT 1.0 but can be achieved using the technique called "Muenchian grouping" (google for it) which looks very complex at first sight but makes sense when you get the hang of it.

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
Reply With Quote
  #4 (permalink)  
Old October 20th, 2008, 08:47 PM
Registered User
 
Join Date: Oct 2008
Location: , , .
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Following is the code I used... Inorder to use XSL 2.0 do I need to install any parsers?


Code:
<?xml version="1.0" encoding="UTF-8"?>
<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:key name="MgrProj" match="/DatabaseData/RecordSet/Record[not(@ProjectId= preceding::Record[1]/@ProjectId)]" use="@PPMName"/>
<xsl:template match="/DatabaseData/RecordSet">
<Dataset>
    <xsl:for-each select="Record[not((@PPMName = preceding::Record/@PPMName))]">
    <Employee EmailAddr="{normalize-space(@PPMEmail)}">    
        <xsl:attribute name="PMHours">
            <xsl:variable name="PPMName" select="@PPMName"/>
            <table border="1">
                 <tr>
                    <th align="left" WIDTH="500">

                    Project#:Name : Status

                    </th>
                    <th align="left" WIDTH="300">
                    Resource
                    </th>
                    <th align="left" WIDTH="200">
                    Function
                    </th>
                    <th align="left" WIDTH="100">
                    Total Hours
                    </th>                            
                 </tr>            
                <tr>
                    <TD width="300" colspan="3" >

                        <b>Total Hours</b>
                    </TD>
                    <TD width="100" align="right">

                        <b>
                        <xsl:value-of select='sum(//Record[normalize-space(@PPMName) = normalize-space($PPMName)]/@Hours)'/>
                        </b>
                    </TD>
                </tr>
            <xsl:for-each select="key('MgrProj', @PPMName)">
            <xsl:variable name="ProjectId" select="@ProjectId"/>            
                <tr>                        
                    <td width = "500" colspan="4">

                    <xsl:value-of select="@ProjectId"/> : <xsl:value-of select="@ProjectName"/> :<xsl:value-of select="@ProjectStatus"/> 

                    </td>
                </tr>
                <xsl:variable name="ResourceNodes" select="//Record[(normalize-space(@PPMName) = normalize-space($PPMName) and @ProjectId = $ProjectId)]"/>                
                <xsl:for-each select="$ResourceNodes[not(normalize-space(@ResourceName)=preceding::Record/@ResourceName) or (position() = last)]">                
                <xsl:if test="@ResourceHrs > 0">
                    <xsl:variable name="ResourceName" select="@ResourceName"/>
                    <tr>                        
                        <td width = "500">

                        &amp;nbsp;

                        </td>
                        <td width = "300">

                        <xsl:value-of select="@ResourceName"/>

                        </td>
                        <td width = "200">

                        &amp;nbsp;

                        </td>
                        <td width = "100" align="right">

                        <B><xsl:value-of select="@ResourceHrs"/></B>

                        </td>
                    </tr>
                    <xsl:for-each select="//Record[(normalize-space(@PPMName) = normalize-space($PPMName) and normalize-space(@ProjectId) = normalize-space($ProjectId)) and (normalize-space(@ResourceName) = normalize-space($ResourceName))]">                    
                        <tr>                        
                            <td width = "500">

                            &amp;nbsp;

                            </td>
                            <td width = "300">

                            &amp;nbsp;

                            </td>                            
                            <td width = "200">

                            <xsl:value-of select="@FunctionName"/>

                            </td>
                            <td width = "100" align="right">

                            <xsl:value-of select="@Hours"/>

                            </td>                            
                        </tr>                                                
                    </xsl:for-each>    
                </xsl:if>                    
                </xsl:for-each>            
            </xsl:for-each>        
            </table>            
        </xsl:attribute>        
    </Employee>                    
    </xsl:for-each>
</Dataset>
</xsl:template>
</xsl:stylesheet>
Baru
Reply With Quote
  #5 (permalink)  
Old October 21st, 2008, 12:52 AM
Registered User
 
Join Date: Oct 2008
Location: , , .
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Do I need to install "Saxon 7" complier on my machine in order to use XSL 2.0 & for-each-group element?

Quote:
quote:Originally posted by mhkay
 This is a standard grouping problem. Look up "grouping" in your favourite Wrox XSLT textbook for the solution.

Grouping is very easy in XSLT 2.0 using the new xsl:for-each-group instruction. It's rather harder in XSLT 1.0 but can be achieved using the technique called "Muenchian grouping" (google for it) which looks very complex at first sight but makes sense when you get the hang of it.

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
Baru
Reply With Quote
  #6 (permalink)  
Old October 21st, 2008, 02:58 AM
samjudson's Avatar
Friend of Wrox
Points: 8,687, Level: 40
Points: 8,687, Level: 40 Points: 8,687, Level: 40 Points: 8,687, Level: 40
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Aug 2007
Location: Newcastle, , United Kingdom.
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
Default

Saxon 9 is the latest version, and will work with .Net applications.

/- Sam Judson : Wrox Technical Editor -/
Reply With Quote
  #7 (permalink)  
Old October 21st, 2008, 03:17 AM
mhkay's Avatar
Wrox Author
Points: 18,487, Level: 59
Points: 18,487, Level: 59 Points: 18,487, Level: 59 Points: 18,487, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

I would certainly recommend Saxon for XSLT 2.0 processing (it's my product, and the market leader!); the current version is 9.1

There are two other XSLT 2.0 processors available, AltovaXML from Altova, and Gestalt from Colin Adams.

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
Reply With Quote
  #8 (permalink)  
Old October 21st, 2008, 03:54 AM
mhkay's Avatar
Wrox Author
Points: 18,487, Level: 59
Points: 18,487, Level: 59 Points: 18,487, Level: 59 Points: 18,487, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

>Following is the code I used...

I've lost track of the thread - I'm not sure why you posted this code. But here are some comments on it.

(a) it's incredibly monolithic. Try to break it up into template rules. Don't use nested for-each loops like this: use xsl:apply-templates at each level, with xsl:template rules to define how each element gets processed.

(b) This is clearly wrong:

<xsl:attribute name="PMHours">
            <xsl:variable name="PPMName" select="@PPMName"/>
            <table border="1">
                 <tr>

It's trying to create a table element within a PMHours attribute. You can't have elements inside attributes. There are various things that might happen when you do this, depending on which processor you are using.

(c) <xsl:for-each select="Record[not((@PPMName = preceding::Record/@PPMName))]">

Better to use XSLT 2.0 grouping, or XSLT 1.0 Muenchian Grouping using keys; but if you must do it this way, you should be using the preceding-sibling axis rather than preceding.

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
Reply With Quote
  #9 (permalink)  
Old October 21st, 2008, 09:03 AM
Registered User
 
Join Date: Oct 2008
Location: , , .
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I am using VB6.0 to generate Emails to each Manager in the format required. I will follow your guidelines and see how I can solve this issue.

Quote:
quote:Originally posted by mhkay
 >Following is the code I used...

I've lost track of the thread - I'm not sure why you posted this code. But here are some comments on it.

(a) it's incredibly monolithic. Try to break it up into template rules. Don't use nested for-each loops like this: use xsl:apply-templates at each level, with xsl:template rules to define how each element gets processed.

(b) This is clearly wrong:

<xsl:attribute name="PMHours">
            <xsl:variable name="PPMName" select="@PPMName"/>
            <table border="1">
                 <tr>

It's trying to create a table element within a PMHours attribute. You can't have elements inside attributes. There are various things that might happen when you do this, depending on which processor you are using.

(c) <xsl:for-each select="Record[not((@PPMName = preceding::Record/@PPMName))]">

Better to use XSLT 2.0 grouping, or XSLT 1.0 Muenchian Grouping using keys; but if you must do it this way, you should be using the preceding-sibling axis rather than preceding.

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
Baru
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
help needed in XSLT ddeokarb XSLT 1 November 22nd, 2007 10:41 AM
XSLT Help Needed JZen XSLT 9 February 22nd, 2007 04:27 AM
xslt help desperately needed daula7 XSLT 2 May 10th, 2006 12:09 PM
help needed regarding xslt pradeep.mallavarapu XSLT 1 April 19th, 2006 05:58 AM
help needed for xslt rameshnarayan XSLT 2 September 19th, 2005 03:58 AM



All times are GMT -4. The time now is 12:22 PM.


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