Solved

Serial number in XSLT

Posted on 2007-03-28
20
1,266 Views
Last Modified: 2013-11-18

I have an XML such as

<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<package>
    <document>
        <document_metadata>
            <first_name>ABC</first_name>
            <middle_name/>
            <last_name>XYZ</last_name>
            <appl>Appl1</appl>
        </document_metadata>

            <document_content>
            <author>
                <year>1895</year>
                <biog></biog>
            </author>
        </document_content>
    </document>

    <document>
        <document_metadata>
            <first_name>Tim</first_name>
            <middle_name/>
            <last_name>Hall</last_name>
            <appl>Appl2</appl>
        </document_metadata>
        <document_content>
                <year>1985</year>
                <biog></biog>
        </document_content>
    </document>

</package>

I need to transform it to an HTML table, which has 5 columns
Serial No. --> Serial No.
Appl --> value of <appl> element
Last --> Value of <last_name> element
Middle -->  Value of <middle_name> element
First --> Value of <first_name> element

I have written the following XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="package">
        <table border="2">
            <tr bgcolor="#C0C0C0">
                <th>Serial No.</th>
                <th>Appl</th>
                <th>Last</th>
                <th>Middle</th>
                <th>First</th>
            </tr>

                <xsl:apply-templates/>
           
        </table>

    </xsl:template>
   
    <xsl:template match="document" >
        <xsl:apply-templates select="document_metadata" />
    </xsl:template>
   
    <xsl:template match="document_metadata">
        <tr>
            <td>111</td>
            <td>
                <xsl:value-of select="appl"/>
            </td>
            <td>
                <xsl:value-of select="last_name"/>
            </td>
            <td>
                <xsl:choose>
                    <xsl:when test="middle_name=''"></xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="middle_name"/>
                    </xsl:otherwise>
                </xsl:choose>
               
            </td>
            <td>
                <xsl:value-of select="first_name"/>
            </td>
        </tr>
    </xsl:template>
   
   
</xsl:stylesheet>

Two things I am unable to do are:
1. Generate a serial no. How to count which row it is. Serial no. will be in the form of 1,2,3 and so on
2. Most of the <middle_name> elements are empty. In my HTML table I have given the border as 2. In HTML When the cells are empty even the border is not displayed. I want to display the border even for empty cells. If we put &nbsp; in an empty cell then the border is displayed. So if I do

<td>
                <xsl:choose>
                    <xsl:when test="middle_name=''">&nbsp;</xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="middle_name"/>
                    </xsl:otherwise>
                </xsl:choose>
               
            </td>
it gives me an error.

Please tell me how to solve these.
0
Comment
Question by:Annabelle_s
20 Comments
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 18813916
1. use  <td><xsl:number count="document"/></td> to count the documents

2. if you want to output &nbsp; you need to define the entity in the XSLT and in the resulting XML
You could use &#160; which is the same thing but can be used without declaration

   <xsl:template match="document_metadata">
        <tr>
            <td><xsl:number count="document"/></td>
            <td>
                <xsl:value-of select="appl"/>
            </td>
            <td>
                <xsl:value-of select="last_name"/>
            </td>
            <td>
                <xsl:choose>
                    <xsl:when test="middle_name=''">&#160;</xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="middle_name"/>
                    </xsl:otherwise>
                </xsl:choose>
           </td>
            <td>
                <xsl:value-of select="first_name"/>
            </td>
        </tr>
    </xsl:template>

cheers

Geert
0
 

Author Comment

by:Annabelle_s
ID: 18813946

>>use  <td><xsl:number count="document"/></td> to count the documents
It displays 1 for each row. The serial number should be incremented for each row
0
 

Author Comment

by:Annabelle_s
ID: 18813955
>>It displays 1 for each row. The serial number should be incremented for each row

i am sorry, its working fine. Old result might be getting cached. i restarted the browser and its working fine. Thanks
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 18813962
welcome
0
 

Author Comment

by:Annabelle_s
ID: 18813982
There's another small problem. I want the alternate rows to be displayed in different colors. So I was trying to do

<xsl:template match="document_metadata">
        <xsl:variable name="count">
            <xsl:number count="document"/>
        </xsl:variable>
        <xsl:variable name="backGround">
            <xsl:choose>
                <xsl:when test="count div 2=0">
                    #C0C0C0;
                </xsl:when>
                <xsl:otherwise>
                    #D2E8E8;
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <tr bgcolor="$backGround">
            <td><xsl:number count="document"/></td>
            <td>
                <xsl:value-of select="appl"/>
            </td>

But all the rows are getting displayed in the same color
0
 

Author Comment

by:Annabelle_s
ID: 18814039
if I try to print

Mod result--<xsl:value-of select="count mod 2"></xsl:value-of>        

i get NaN. What the reason for getting NaN
0
 

Author Comment

by:Annabelle_s
ID: 18814041
>>Mod result--<xsl:value-of select="count mod 2"></xsl:value-of>        
Sorry it should have been

Mod result--<xsl:value-of select="$count mod 2"></xsl:value-of>        
0
 

Author Comment

by:Annabelle_s
ID: 18814059
If I do
        Mod result--<xsl:value-of select="$count mod 2=0"></xsl:value-of>    

It prints alterante true and false. But then why doesnt the when/otherwise statement work.
0
 

Author Comment

by:Annabelle_s
ID: 18814077
Even when I print
        BackGround--<xsl:value-of select="$backGround"></xsl:value-of>
i get alternate value. But can't see the correct results. All rows are dispalying with the same color.
0
 

Author Comment

by:Annabelle_s
ID: 18814082
I think doing this will not work

<tr bgcolor="$backGround">

Since <tr> is an HTML tag and $backGround is an XSLT variable. Am I correct? Then whats the way to do it.
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
LVL 60

Expert Comment

by:Geert Bormans
ID: 18814101
I was bringing the kids to school, so I missed part of the conversation

   <xsl:template match="document_metadata">
        <xsl:variable name="rowCount">
            <xsl:number count="document"/>
        </xsl:variable>
        <tr>
            <xsl:attribute name="bgcolor">
                <xsl:choose>
                    <xsl:when test="$rowCount mod 2 = 1">red</xsl:when>
                    <xsl:otherwise>yellow</xsl:otherwise>
                </xsl:choose>
            </xsl:attribute>
           
            <td><xsl:value-of select="$rowCount"></xsl:value-of></td>

works for me, on the condition that you set the XSLT version to 1.0
XSLT2.0 doesn't do automatic casting between types, because of the strong typing
and xsl:number creates a string, not a number, hence NaN

If you don't use XSLT2 constructs, set the version to 1
otherwise make an explicit cast,
I will show that in a minute

cheers

Geert
0
 
LVL 8

Expert Comment

by:thomas908
ID: 18814108
This works for me, with the code you posted
        <tr bgcolor="{$backGround}">
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 18814109
<tr bgcolor="$backGround">
will output the literal string $background
you need to use attribute value templates
in order to evaluate the XPath
<tr bgcolor="{$backGround}">

cheers

Geert
0
 

Author Comment

by:Annabelle_s
ID: 18814130
>><tr bgcolor="{$backGround}">
This works fine. It displays alternate rows in differnet colors.
But why is the color display so different

The color display when I do this
<tr bgcolor="#D2E8E8">
 <td>Serial No.</td>

is totally different from

        <tr bgcolor="{$backGround}">
with the same value of $backGround, that is   #D2E8E8
Also, in Firefox, alterante coloring is not working
           
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 18814134
Forget my casting comment,
aparently xsl:number returns an integer
so all is OK
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 18814137
Is this processing in a browser?
If it is you have to set the stylesheet version to 1.0,
browsers don't support 2.0 and sometimes act funny on the wrong version number

cheers

Geert
0
 

Author Comment

by:Annabelle_s
ID: 18814150
I did this
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output version="1.0" method="html" encoding="ISO-8859-1" />

Now it works fine in Firefox but coloring is still messed up in IE6
0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 200 total points
ID: 18814168
instead of <tr bgcolor="{$backGround}">

can you try this?

<tr style="background-color: {$backGround};">
0
 

Expert Comment

by:unifi
ID: 25043020

<cell>
<xsl:value-of select="position()"/>
</cell>
is the easiest way to generate serial numbers :)
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 25043089
> is the easiest way to generate serial numbers :)

this question has been long closed by the way....

but you are only right in a very specific case,
if position() acts upon a nodeset that is only the document

In the example above, position() would not have worked for various reasons
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Most of the sites are being standardized with W3C Web Standards. W3C provides lot of web standard services to the web. They have the web specification, process and documentation for all the web standards. You can apply HTML, CSS and Accessibility st…
Preface This is the third article about the EE Collaborative Login Project. A Better Website Login System (http://www.experts-exchange.com/A_2902.html) introduces the Login System and shows how to implement a login page. The EE Collaborative Logi…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
The viewer will learn how to count occurrences of each item in an array.

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

27 Experts available now in Live!

Get 1:1 Help Now