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 July 30th, 2003, 11:15 AM
Registered User
 
Join Date: Jul 2003
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Default Renderering a browser support table

Hello!

Could someone show me a template that will transform this XML:

<user-agent platform="Macintosh" name="Internet Explorer" version="5.5">A</user-agent>
<user-agent paltform="Macintosh" name="Safari" version="1.0">B</user-agent>

<user-agent platform="Linux" name="Mozilla" version="1.0">C</user-agent>
<user-agent platform="Linux" name="Mozilla" version="1.4">D</user-agent>
<user-agent platform="Linux" name="Netscape" version="7.1">E</user-agent>

<user-agent platform="Win32" name="Internet Explorer" version="5.0">F</user-agent>
<user-agent platform="Win32" name="Internet Explorer" version="5.5">G</user-agent>
<user-agent platform="Win32" name="Internet Explorer" version="6.0">H</user-agent>
<user-agent platform="Win32" name="Mozilla" version="1.0">I</user-agent>
<user-agent platform="Win32" name="Mozilla" version="1.2">J</user-agent>
<user-agent platform="Win32" name="Mozilla" version="1.4">K</user-agent>
<user-agent platform="Win32" name="Netscape" version="6.1">L</user-agent>
<user-agent platform="Win32" name="Netscape" version="7.1">M</user-agent>
<user-agent platform="Win32" name="Opera" version="7.11">N</user-agent>

To this HTML:

<table border="1" cellpadding="2" cellspacing="0">
    <tr>
        <th colspan="14">Browser Support Key</th>
    </tr>
    <tr>
        <td colspan="2">Macintosh</td>
        <td colspan="3">Linux</td>
        <td colspan="9">Win32</td>
    </tr>
    <tr>
        <td>Internet Explorer</td>
        <td>Safari</td>
        <td colspan="2">Mozilla</td>
        <td>Netscape</td>
        <td colspan="3">Internet Explorer</td>
        <td colspan="3">Mozilla</td>
        <td colspan="2">Netscape</td>
        <td>Opera</td>
    </tr>
    <tr>
        <td>5.5</td>
        <td>1.0</td>
        <td>1.0</td>
        <td>1.4</td>
        <td>7.1</td>
        <td>5.0</td>
        <td>5.5</td>
        <td>6.0</td>
        <td>1.0</td>
        <td>1.2</td>
        <td>1.4</td>
        <td>6.1</td>
        <td>7.1</td>
        <td>7.11</td>
    </tr>
    <tr>
        <td>A</td>
        <td>B</td>
        <td>C</td>
        <td>D</td>
        <td>E</td>
        <td>F</td>
        <td>G</td>
        <td>H</td>
        <td>I</td>
        <td>J</td>
        <td>K</td>
        <td>L</td>
        <td>M</td>
        <td>N</td>
    </tr>
</table>

Do I have to do recursive XSL to go throught with this one?

Thanks in advance.
/Andrin
 
Old July 31st, 2003, 02:17 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 147
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to armmarti
Default

Hi,

First of all, the attribute name of the second "user-agent" element must
 be "platform" instead of "paltform".

Quote:
quote:
Do I have to do recursive XSL to go throught with this one?
I think the stylesheet which will output the desired table should be of "navigational" and/or "computational" type(or design pattern). I don't see
reasons to write recursive templates here.

Nevertheless, here is the stylesheet:

Code:
 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="platform" match="user-agent" use="@platform"/>

    <xsl:variable name="all-agents" select="/*/user-agent"/>
    <xsl:variable name="distinct-platforms" select="$all-agents[generate-id(.) = generate-id(key('platform', @platform)[1])]"/>

    <xsl:template match="/">
        <html>
            <head>
                <title>Agents</title>
            </head>
            <body>
                <table border="1" cellpadding="2" cellspacing="0">
                    <tbody>
                         <xsl:variable name="agents-count" select="count($all-agents)"/>    
                        <tr>
                            <th>
                                    <xsl:if test="$agents-count &gt; 1">
                                        <xsl:attribute name="colspan">
                                            <xsl:value-of select="$agents-count"/>
                                        </xsl:attribute> 
                                    </xsl:if>
                                Browser Support Key
                             </th>
                        </tr>
                        <tr>
                            <xsl:for-each select="$distinct-platforms">
                                <xsl:variable name="col-span" select="count(key('platform', @platform))"/>
                                <td>
                                    <xsl:if test="$col-span &gt; 1">
                                        <xsl:attribute name="colspan">
                                            <xsl:value-of select="$col-span"/>
                                        </xsl:attribute>
                                    </xsl:if>
                                    <xsl:value-of select="@platform"/>
                                </td> 
                            </xsl:for-each>                        
                        </tr>
                        <tr>
                            <xsl:for-each select="$distinct-platforms">
                                <xsl:variable name="current-platform" select="@platform"/>
                                <xsl:variable name="distinct-names-in-platforms" select="key('platform', @platform)[not(@name = preceding-sibling::user-agent[@platform = current()/@platform]/@name)]"/>
                                <xsl:for-each select="$distinct-names-in-platforms">
                                    <xsl:variable name="current-group-size" select="count(key('platform', $current-platform)[@name = current()/@name])"/>
                                    <td>
                                        <xsl:if test="$current-group-size &gt; 1">
                                            <xsl:attribute name="colspan">
                                                <xsl:value-of select="$current-group-size"/>
                                            </xsl:attribute>
                                        </xsl:if>
                                        <xsl:value-of select="@name"/>
                                    </td>                                    
                                </xsl:for-each>    
                            </xsl:for-each>                            
                        </tr>
                        <tr>
                            <xsl:for-each select="$all-agents">
                                <td>
                                    <xsl:value-of select="@version"/>
                                </td>
                            </xsl:for-each>
                        </tr>
                        <tr>
                            <xsl:for-each select="$all-agents">
                                <td>
                                    <xsl:value-of select="."/>
                                </td>
                            </xsl:for-each>
                        </tr>                        
                    </tbody>
                </table>
            </body>
        </html>
    </xsl:template>

</xsl:stylesheet>
By the way, the stylesheet will output the table correctly when "user-agent" elements will be added (deleted) to (from) the XML source.

Regards,
Armen
 
Old July 31st, 2003, 03:08 AM
Registered User
 
Join Date: Jul 2003
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks a lot Armen :-)

I saw that "paltform" the minute I posted it and I didn´t bother to edit the topic :-(

The XSL looks very complicated and I am sure it would have taken me to the end of this year to fix this one. Again, tnx!

/Andrin
 
Old July 31st, 2003, 04:12 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 147
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to armmarti
Default

You are welcome Andrin.
If you have questions or need explanations, let me know please.

Regards,
Armen
 
Old August 1st, 2003, 03:56 AM
Registered User
 
Join Date: Jul 2003
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
quote:
If you have questions or need explanations, let me know please.
A little explanation would be fine if you have time and will :-) I´m not very used to keys and variables in XSLT and I don´t have a clue what you´re doing when you use the generate-id() function. And what if I didn´t use attributes? If I was about to select distinct element based upon their names (local-name)? Would that complicate things?

Cheers
/Andrin
 
Old August 1st, 2003, 05:36 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 147
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via Yahoo to armmarti
Default

Quote:
quote:
A little explanation would be fine if you have time and will :-) I?m not very used to keys and variables in XSLT and I don?t have a clue what you?re doing when you use the generate-id() function.
I think for deep understanding of keys and variables it'll be better to refer to Michael Kay's "XSLT Programmer's reference"(it's an excellent source for XSLT in general), or you can look at the W3C's XSLT 1.0 specification: http://www.w3.org/TR/xslt
;
another online snippet on keys: http://saxon.sourceforge.net/saxon6....s.html#xsl:key

I'll try to explain the point concerned with the grouping technique(well known Muenchian method).

The XPath expression
Code:
$all-agents[generate-id(.) = generate-id(key('platform', @platform)[1])]
actually selects all such "user-agent" elements, which have distinct "platform" attribute value(and each of those "user-agent" elements is the first one(in document order) in its respective group). Look how it's going on: generate-id(node) function returns a unique id(string) for the parameter-node; key('platform', @platform)
 selects all "user-agent" elements having the same value for "platform" attribute as the context node's "platform" attribute; then we select the first one among them(the predicate [1]) and finally we use the function generate-id() to test wheather the context node is the first "representative" of the group or not, and if so, select it. As a result, the XPath above returns "representatives" of groups(each group consists of "user-agent" elements having the same value for the attribute "platform").
For further clarifications see http://www.jenitennison.com/xslt/gro...muenchian.html

Keys make XPath expression evaluation more effective; they are similar to indexes in relational databases.

Quote:
quote:
And what if I didn?t use attributes? If I was about to select distinct element based upon their names (local-name)? Would that complicate things?
No, in this concrete situation you'll just need to slightly change the code. When you'll fully understand the concept of "key", it'll be obvious.

Regards,
Armen
 
Old August 1st, 2003, 08:34 AM
Registered User
 
Join Date: Jul 2003
Posts: 8
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Again I thank you Armen :-)

I have XSLT 2nd Ed. Progr. Ref. by Michael Kay and I have read it but to be onest I don´t understand a thing when it comes to keys... Someday I will I hope :-)

Tnx
/Andrin





Similar Threads
Thread Thread Starter Forum Replies Last Post
Browser Support for XSLT 2.0 dennis_wimer XSLT 6 May 8th, 2010 04:25 PM
How can we put the Table in the center of browser nitinsuri1980 ASP.NET 1.0 and 1.1 Professional 1 April 2nd, 2006 04:09 AM
How can we put the Table in the center of browser? nitinsuri1980 ASP.NET 1.0 and 1.1 Basics 1 April 1st, 2006 10:00 PM
Table bottom of browser window donthomaso Dreamweaver (all versions) 0 October 15th, 2005 06:56 PM





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