Subject: Debugging XSLT
Posted By: Russ Post Date: 10/2/2006 6:25:23 AM
I have a xml file that I am translating into html.  I have it working with one exception.  When I view the html document,  what I see is my data formatted in a nice table.  However, I see the unformatted data appearing twice above the table. I could post more information, but this post would be rather long, so instead, I'll just post the html in hopes someone has seen this behavior before and can recommend a way to eliminate it.


<html lang="en" xmlns:xalan="http://xml.apache.org/xslt">
<body>
<h2>Document Details</h2>
<h3>Total Documents:1</h3>
<table border="1" cellpadding="5">
<tr>
<td><b>Sequence</b></td><td><b>DocumentId</b></td><td><b>Create Date</b></td><td><b>Create Time</b></td><td><b>Create Operator</b></td><td><b>ExternalDocKey</b></td><td><b>ExternalSysName</b></td><td><b>Mail Desc</b></td><td><b>Mail Id</b></td><td><b>ArchBoxId</b></td><td><b>MagFldName</b></td><td><b>MagFlg</b></td><td><b>Fax Nbr</b></td><td><b>Begin Page</b></td><td><b>End Page</b></td><td><b>PageTotal</b></td><td><b>WrkStnId</b></td><td><b>File Size</b></td><td><b>File Type</b></td><td><b>PiDocType</b></td><td><b>Annotation</b></td><td><b>Doc Content Seq</b></td><td><b>Doc Content Desc</b></td><td><b>Begin Page</b></td><td><b>End Page</b></td><td><b>PageTotal</b></td><td><b>Secure Flag</b></td><td><b>TaskId</b></td>
</tr>
<tr>
<td>1</td><td>d0609080.003</td><td>2006-09-08</td><td>10:17:53</td><td>empty</td><td>empty</td><td>empty</td><td>REPORT</td><td>C:\PROGRAM FILES\CLIENT\EMS\PAYREJ.TXT</td><td>empty</td><td>empty</td><td>empty</td><td>empty</td> 
  1
  
    1
    d0609080.003 
    2006-09-08 
    10:17:53 
     
         REPORT 
         C:\PROGRAM FILES\CLIENT\EMS\PAYREJ.TXT 
    
    <td>1</td><td>10</td><td>10</td>
    piinit
    0.0 
    TEXT
    
       1
       split
       
          1
          5
          10
       
       N
       t0609300001
    
  
<td>piinit</td><td>0.0</td><td>empty</td><td>TEXT</td><td>empty</td><td>1</td><td>split</td> 
  1
  
    1
    d0609080.003 
    2006-09-08 
    10:17:53 
     
         REPORT 
         C:\PROGRAM FILES\CLIENT\EMS\PAYREJ.TXT 
    
    
       1
       10
       10
    
    piinit
    0.0 
    TEXT
    
       1
       split
       <td>1</td><td>5</td><td>10</td>
       N
       t0609300001
    
  
<td>N</td><td>t0609300001</td>
</tr>
</table>
</body>
</html>


Thank you for reading my post and any words of encouragement you can offer.

Russ

Reply By: mhkay Reply Date: 10/2/2006 6:47:36 AM
You want me to look at your output and guess what incorrect program might have generated it?

Seriously?

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply By: Russ Reply Date: 10/2/2006 7:11:28 AM
Michael:

Thanks for your reply...  I realize is was a shot in the dark with just posting the html, but I was hoping others may had seen this behavior before.

Here is the calling order of the xsl.
1. DocSearchResults
2. documents
3. document
4. pagerange
5. docContent
6. pagerange

Here is the xsl.


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"
    xmlns:xalan="http://xml.apache.org/xslt">
    
<xsl:include href="documents.xsl"/>

<xsl:output method="html" encoding="iso-8859-1" indent="yes"/>

    
    <xsl:variable name="table-heading">
            <td><b>Sequence</b></td>
            <td><b>DocumentId</b></td>
            <td><b>Create Date</b></td>
            <td><b>Create Time</b></td>
            <td><b>Create Operator</b></td>
            <td><b>ExternalDocKey</b></td>
            <td><b>ExternalSysName</b></td>
            <td><b>Mail Desc</b></td>
            <td><b>Mail Id</b></td>
            <td><b>ArchBoxId</b></td>
            <td><b>MagFldName</b></td>
            <td><b>MagFlg</b></td>
            <td><b>Fax Nbr</b></td>
            <td><b>Begin Page</b></td>
            <td><b>End Page</b></td>
            <td><b>PageTotal</b></td>
            <td><b>WrkStnId</b></td>
            <td><b>File Size</b></td>
            <td><b>File Type</b></td>
            <td><b>PiDocType</b></td>
            <td><b>Annotation</b></td>
            <td><b>Doc Content Seq</b></td>
            <td><b>Doc Content Desc</b></td>
            <td><b>Begin Page</b></td>
            <td><b>End Page</b></td>
            <td><b>PageTotal</b></td>
            <td><b>Secure Flag</b></td>
            <td><b>TaskId</b></td>    
    </xsl:variable>
    
<xsl:template match="/">

<html lang="en">
  <body>
       <h2>Document Details</h2>
       <h3>Total Documents:<xsl:value-of select="Documents/count"/></h3>
           <table  border="1" cellpadding="5">
              <tr>
                <xsl:copy-of select="$table-heading"/>
              </tr>
               <!-- This is to pick up documents -->
               <xsl:call-template name="documents">
                  <xsl:with-param name="documentsNode" select="Documents"/>
               </xsl:call-template>
           </table>
  </body>
</html>

    </xsl:template>
</xsl:stylesheet>




<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"
    xmlns:xalan="http://xml.apache.org/xslt">
    

<xsl:include href="document.xsl"/>


<xsl:output method="html" encoding="iso-8859-1" indent="yes"/>
  
 <xsl:template name="documents">
    <xsl:param name="documentsNode"/>
    <tr><xsl:call-template name="document">
             <xsl:with-param name="documentNodes" select="$documentsNode/*"/>
        </xsl:call-template>
    </tr>
  </xsl:template> 
</xsl:stylesheet>



<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"
    xmlns:xalan="http://xml.apache.org/xslt">
    
<xsl:include href="pageRange.xsl"/>
<xsl:include href="docContent.xsl"/>

<xsl:output method="html" encoding="iso-8859-1" indent="yes"/>
  
 <xsl:template name ="document" >
        <xsl:param name="documentNodes"/>
                
                <td><xsl:value-of select="$documentNodes/id"/></td>
                               
                <xsl:variable name="docid" select="$documentNodes/docid"/>
                <xsl:choose>
                   <xsl:when test="$docid = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($docid)>0">
                     <td><xsl:value-of select="$docid"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                
                
                <xsl:variable name="createdate" select="$documentNodes/createdate"/>
                <xsl:choose>
                   <xsl:when test="$createdate = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($createdate)>0">
                     <td><xsl:value-of select="$createdate"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                
                <xsl:variable name="createtime" select="$documentNodes/createtime"/>
                <xsl:choose>
                   <xsl:when test="$createtime = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($createtime)>0">
                     <td><xsl:value-of select="$createtime"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>

                <xsl:variable name="createoper" select="$documentNodes/createoper"/>
                <xsl:choose>
                   <xsl:when test="$createoper = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($createoper)>0">
                     <td><xsl:value-of select="$createoper"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                
                <xsl:variable name="extdockey" select="$documentNodes/extdockey"/>
                <xsl:choose>
                   <xsl:when test="$extdockey = null">
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($extdockey)>0">
                     <td><xsl:value-of select="$extdockey"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>               
                
                <xsl:variable name="extsystemname" select="$documentNodes/extsystemname"/>
                <xsl:choose>
                   <xsl:when test="$extsystemname = null">
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($extsystemname)>0">
                     <td><xsl:value-of select="$extsystemname"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                
                <xsl:variable name="maildesc" select="$documentNodes/mailinfo/maildesc"/>
                <xsl:choose>
                   <xsl:when test="$maildesc = null">
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($maildesc)>0">
                     <td><xsl:value-of select="$maildesc"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                
                <xsl:variable name="mailid" select="$documentNodes/mailinfo/mailid"/>
                <xsl:choose>
                   <xsl:when test="$mailid = null">
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($mailid)>0">
                     <td><xsl:value-of select="$mailid"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                
                <xsl:variable name="archboxid" select="$documentNodes/archboxid"/>
                <xsl:choose>
                   <xsl:when test="$archboxid = null">
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($archboxid)>0">
                     <td><xsl:value-of select="$archboxid"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                
                <xsl:variable name="magfldname" select="$documentNodes/magfldname"/>
                <xsl:choose>
                   <xsl:when test="$magfldname = null">
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($magfldname)>0">
                     <td><xsl:value-of select="$magfldname"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                
                <xsl:variable name="magflag" select="$documentNodes/magflag"/>
                <xsl:choose>
                   <xsl:when test="$magflag = null">
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($magflag)>0">
                     <td><xsl:value-of select="$magflag"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                
                <xsl:variable name="faxnbr" select="$documentNodes/faxnbr"/>
                <xsl:choose>
                   <xsl:when test="$faxnbr = null">
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($faxnbr)>0">
                     <td><xsl:value-of select="$faxnbr"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                
                
                <!-- This is to pick up page ranges for Document -->
                <xsl:apply-templates mode="docPages"/>  
                     
                <xsl:variable name="wrkstnid" select="$documentNodes/wrkstnid"/>
                <xsl:choose>
                   <xsl:when test="$wrkstnid = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($wrkstnid)>0">
                     <td><xsl:value-of select="$wrkstnid"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                
                <!-- This will always be populated -->
                <td><xsl:value-of select="$documentNodes/filesize"/></td>
                
                <xsl:variable name="filetype" select="$documentNodes/filetype"/>
                <xsl:choose>
                   <xsl:when test="$filetype = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($filetype)>0">
                     <td><xsl:value-of select="$filetype"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                
                <xsl:variable name="pidoctype" select="$documentNodes/pidoctype"/>
                <xsl:choose>
                   <xsl:when test="$pidoctype = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($pidoctype)>0">
                     <td><xsl:value-of select="$pidoctype"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>

                <xsl:variable name="annotations" select="$documentNodes/annotations"/>
                <xsl:choose>
                   <xsl:when test="$annotations = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($annotations)>0">
                     <td><xsl:value-of select="$annotations"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
                </xsl:choose>
                 
               <!-- This is to pick up Doc Content -->
               <xsl:call-template name="docContent" >
                  <xsl:with-param name="docContentNode" select="$documentNodes/DocumentContent"/>
               </xsl:call-template>
           
  </xsl:template> 
</xsl:stylesheet>





<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"
    xmlns:xalan="http://xml.apache.org/xslt">
    


<xsl:output method="html" encoding="iso-8859-1" indent="yes"/>

    <xsl:template mode="docPages" match="Document/pagerange">
          
          <xsl:variable name="begpage1" select="begpage"/>
                <xsl:choose>
                   <xsl:when test="$begpage1 = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($begpage1)>0">
                     <td><xsl:value-of select="$begpage1"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
           </xsl:choose>
           <xsl:variable name="endpage1" select="endpage"/>
                <xsl:choose>
                   <xsl:when test="$endpage1 = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($endpage1)>0">
                     <td><xsl:value-of select="$endpage1"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
           </xsl:choose>
            <xsl:variable name="pagetotal1" select="pagetotal"/>
                <xsl:choose>
                   <xsl:when test="$pagetotal1 = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($pagetotal1)>0">
                     <td><xsl:value-of select="$pagetotal1"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
           </xsl:choose>
    </xsl:template> 
    
    <xsl:template mode="docContentPages" match="DocumentContent/pagerange">
          
          <xsl:variable name="begpage2" select="begpage"/>
                <xsl:choose>
                   <xsl:when test="$begpage2 = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($begpage2)>0">
                     <td><xsl:value-of select="$begpage2"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
           </xsl:choose>
           <xsl:variable name="endpage2" select="endpage"/>
                <xsl:choose>
                   <xsl:when test="$endpage2 = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($endpage2)>0">
                     <td><xsl:value-of select="$endpage2"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
           </xsl:choose>
            <xsl:variable name="pagetotal2" select="pagetotal"/>
                <xsl:choose>
                   <xsl:when test="$pagetotal2 = null">
                      <td><xsl:text>empty</xsl:text></td>
                   </xsl:when>
                   <xsl:when test="string-length($pagetotal2)>0">
                     <td><xsl:value-of select="$pagetotal2"/></td>
                   </xsl:when>
                   <xsl:otherwise>
                     <td><xsl:text>empty</xsl:text></td>
                   </xsl:otherwise>
           </xsl:choose>
    </xsl:template> 

</xsl:stylesheet>




<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"
    xmlns:xalan="http://xml.apache.org/xslt">
    
<xsl:include href="pageRange.xsl"/>

<xsl:output method="html" encoding="iso-8859-1" indent="yes"/>
   
     <xsl:template name="docContent" >
           <xsl:param name="docContentNode"/>
            <xsl:variable name="id" select="$docContentNode/id"/>
             <xsl:choose>
                  <xsl:when test="$id = null">
                    <td><xsl:text>empty</xsl:text></td>
                  </xsl:when>
                  <xsl:when test="string-length($id)>0">
                    <td><xsl:value-of select="$id"/></td>
                  </xsl:when>
                  <xsl:otherwise>
                    <td><xsl:text>empty</xsl:text></td>
                  </xsl:otherwise>
             </xsl:choose>
                
             <xsl:variable name="contentdesc" select="$docContentNode/contentdesc"/>
             <xsl:choose>
                  <xsl:when test="$contentdesc = null">
                    <td><xsl:text>empty</xsl:text></td>
                  </xsl:when>
                  <xsl:when test="string-length($contentdesc)>0">
                    <td><xsl:value-of select="$contentdesc"/></td>
                  </xsl:when>
                  <xsl:otherwise>
                    <td><xsl:text>empty</xsl:text></td>
                  </xsl:otherwise>
             </xsl:choose>   
            
            
            <!-- This is to get page ranges -->
            <xsl:apply-templates mode="docContentPages" />
           
            
            <xsl:variable name="securedflg" select="$docContentNode/securedflg"/>
             <xsl:choose>
                  <xsl:when test="$securedflg = null">
                    <td><xsl:text>empty</xsl:text></td>
                  </xsl:when>
                  <xsl:when test="string-length($securedflg)>0">
                    <td><xsl:value-of select="$securedflg"/></td>
                  </xsl:when>
                  <xsl:otherwise>
                    <td><xsl:text>empty</xsl:text></td>
                  </xsl:otherwise>
             </xsl:choose>

             <xsl:variable name="taskid" select="$docContentNode/taskid"/>
             <xsl:choose>
                  <xsl:when test="$taskid = null">
                    <td><xsl:text>empty</xsl:text></td>
                  </xsl:when>
                  <xsl:when test="string-length($taskid)>0">
                    <td><xsl:value-of select="$taskid"/></td>
                  </xsl:when>
                  <xsl:otherwise>
                    <td><xsl:text>empty</xsl:text></td>
                  </xsl:otherwise>
             </xsl:choose>
    </xsl:template> 
</xsl:stylesheet>


Reply By: mhkay Reply Date: 10/2/2006 8:46:33 AM
This is better, but I'm not going to do your debugging for you. There's nothing that leaps out of the page here as obviously wrong. You're just going to have to step through the logic to see where it's producing faulty output. If you isolate a construct that's producing output you don't understand, the come back to the forum with a cut-down example that demonstrates the problem.

Some suggestions for debugging:

(a) use an XSLT debugger such as Stylus Studio or oXygen

(b) use a schema aware XSLT 2.0 processor such as Saxon 8.x: if you switch on validation of the output against the XHTML schema, you'll get error messages that pinpoint which lines of the stylesheet are generating invalid XHTML

(c) or simple put xsl:message statements into your code to see what path it is taking.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply By: Russ Reply Date: 10/2/2006 9:18:59 AM
Michael:

   Well, to be blunt, I was not expecting you to debug a thing for me.  This is why I was reluctant to add the xsl from the onset.
All to many times, developers do not want to learn, they just want something to work--thus the need for 1000 monkies to do the work of one
good programmer with a good reference book in his hand (yours may I add ;-) ).  What I was hoping for was some pointers on how I could
go about accomplishing my own debugging and isolation of the fault.   I do not learn a thing about my style or understanding of XSLT
if I rely on others to point out my own mistakes.


I think I got what I was looking for in this forum,
some recommendations on how to go about isolating the issue.


Thanks for all your encouragement.

Russ


Go to topic 50496

Return to index page 159
Return to index page 158
Return to index page 157
Return to index page 156
Return to index page 155
Return to index page 154
Return to index page 153
Return to index page 152
Return to index page 151
Return to index page 150