[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] Reading two documents


Subject: [xsl] Reading two documents
From: "Sindigi, Ganesh K" <SindiGK@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 26 May 2004 11:00:19 -0600

Hello,

I need to read two xml documents, to generate a report.  My problem is as
described below.

First document(headers) contains information like report title, field
headers,
whether a field should be displayed or not.  Second document contains 
the data for the report.  Each such field is linked together with 
attribute 'id' of corresponding element/s.  Each displayable field/element
has
an attribute 'display' as true/false.
Also, the first file contains order in which fields needs to be displayed. 
The data file could contain data items in any order.  These two files are 
received from a different interface.  I have no control on the both of the 
input sources.  The size of data file could be in 10s of MB.

The report needs to be generated with headers & orders from first docuemnt.

This report could contain nested data for fields like fieldGroup which is 
determined by attribute rowCount of element fieldGroup.

I am using xsl:key to retrieve the headers from the first document.  I am
able
to generate the report when the elements are in the same sequence in both
documents and all of them have attribut display=true.
I am facing problem when the order/sequence of elements are different and
some
of the elements have display=false.
I tried to read two documents simultaneously, but could not cross-reference.

I need to come up with an XSL to achieve (in an efficient way) both
- follow the order of data displayed as specified in first (headers) file
- have control on alignment of html-tables

Also, the report needs to be generated in text format.  I think I should go
for
XSL-FO for this so that i have proper alignment.  Please suggest

I am finding it difficult to align the titles columns with the data
displayed.

Please suggest me how I could achieve this.  There could be some different
or
better approaches to this, it could be helpful if you direct me towards it.

Thanks,
Ganesh.


Here is XML headers (first) document, source1:

<customerList id="regular" title="Regular Customers ">
<customer >
<field id="customerId" title="Customer Id" display="true"/>
<field id="customerName" title="Customer Name" display="true"/>
<fieldGroup rowcount="1" id="homeAddress" title="Home Address"
display="true">
<fieldList>
<field id="street" title="Street" display="true"/>
<field id="city" title="City" display="true"/>
<field id="state" title="State" display="true"/>
</fieldList>
</fieldGroup>
<fieldGroup rowCount="n" id="companyAddress" title="Company Address"
display="true">
<fieldList>
<field id="street" title="Street" display="true"/>
<field id="city" title="City" display="true"/>
<field id="state" title="State" display="false"/>
</fieldList>
</fieldGroup>
</customer>
</customerList>

Here is XML data document, source2:

<customerList id="regular" >
   <customer >
      <field id="customerName">Customer X</field>
      <field id="customerId">custX</field>
      <fieldGroup id="homeAddress">
         <data>
            <fieldList>
               <field id="street">88th St</field>
               <field id="city">Cheyenne</field>
               <field id="state">WY</field>
            </fieldList>
         </data>
      </fieldGroup>
      <fieldGroup id="companyAddress">
         <data>
            <fieldList>
               <field id="street">128th Street</field>
               <field id="city">Bloomfield</field>
               <field id="state">CO</field>
            </fieldList>
            <fieldList>
               <field id="street">16th Street</field>
               <field id="city">TeaNeck</field>
               <field id="state">NY</field>
            </fieldList>
         </data>
      </fieldGroup>
   </customer>
   <customer >
      <field id="customerName">Customer Y</field>
      <field id="customerId">custY</field>
      <fieldGroup id="homeAddress">
         <data>
            <fieldList>
               <field id="street">Amber St </field>
               <field id="city">Madison</field>
               <field id="state">MI</field>
            </fieldList>
         </data>
      </fieldGroup>
      <fieldGroup id="companyAddress">
         <data>
            <fieldList>
               <field id="street">S. Hammerfield Pkwy</field>
               <field id="city">Chicago</field>
               <field id="state">IL</field>
            </fieldList>
            <fieldList>
               <field id="street">16th Street</field>
               <field id="city">Madison</field>
               <field id="state">MI</field>
            </fieldList>
         </data>
      </fieldGroup>
   </customer>
</customerList>...

The headers File is passed in as parameter to the xsl processor.
-PARAM headersFile source1.xml

Here is stylesheet format.xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output indent="yes" method="html"/>

   <xsl:key name="customerLookup" match="customerList/customer"
      use="ancestor-or-self::customerList/@id"/>

   <xsl:param name="headersFile" select="''"/>

   <!-- Document containing headers/labels for the report  -->
   <xsl:variable name="headers" select="document($headersFile)"/>

   <xsl:variable name="fieldHeaders"
      select="document($headersFile)/customerList"/>

   <xsl:template match="/">
      <html>
         <body>
         <xsl:apply-templates/>
         </body>
      </html>
   </xsl:template>

  <xsl:template match="customerList">
      <h1 align="center">
         <xsl:for-each select="$fieldHeaders">
            <xsl:value-of select="@title"/>
         </xsl:for-each>
      </h1>
      <table border="1" align="center">
         <tr>
            <xsl:call-template name="pTH">
               <xsl:with-param name="cT" select="."/>
            </xsl:call-template>
         </tr>
      <xsl:apply-templates />
      </table>
      <p></p>
   </xsl:template>

   <xsl:template match="customer">
      <tr>
      <xsl:apply-templates />
      </tr>
   </xsl:template>


   <xsl:template name="pTH">
      <xsl:param name="cT"/>
      <xsl:for-each select="$fieldHeaders">
         <xsl:for-each select="key('customerLookup',
$cT/ancestor-or-self::customerList/@id)/*">
            <xsl:variable name="switch" select="name(.)"/>
            <xsl:choose>
               <xsl:when test=" $switch = 'fieldGroup' ">
                  <td>
                  <xsl:call-template name="fTH">
                     <xsl:with-param name="ncT" select="."/>
                  </xsl:call-template>
                  </td>
               </xsl:when>
               <xsl:when test=" $switch = 'field' ">
                     <td bgcolor="FFAACC"
style="font-family:verdana;font-size:100%;color:black">
                        <xsl:value-of select="@title"/>
                     </td>
               </xsl:when>
            </xsl:choose>
         </xsl:for-each>
      </xsl:for-each>

   </xsl:template>

   <xsl:template name="fTH">
      <xsl:param name="ncT"/>
      <xsl:variable name="noOfCols" select="count($ncT/fieldList/field)"/>
      <table border="1" width="100%" height="100%">
      <tr>
         <td colspan="{$noOfCols}" bgcolor="88FF88"
            style="font-family:verdana;font-size:100%;color:black">
            <xsl:value-of select="$ncT/@title"/>
         </td>
      </tr>
      <tr>
         <xsl:for-each select="$ncT/fieldList/field">
               <td bgcolor="FFAACC"
                  style="font-family:verdana;font-size:100%;color:black">
                  <xsl:value-of select="@title"/>
               </td>
         </xsl:for-each>
      </tr>
      </table>
   </xsl:template>

   <xsl:template match="fieldGroup">
      <td><table border="1" width="100%" height="100%">
         <xsl:apply-templates />
      </table></td>
   </xsl:template>
   <xsl:template match="fieldList">

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

   </xsl:template>

   <xsl:template match="field">
      <td>
         <xsl:value-of select="text()"/>
      </td>
   </xsl:template>

   <xsl:template match="text()"/>
</xsl:stylesheet>

Desired Output html :

----------------------------------------------------------------------------
----
Customer Id	Customer Name	  Home Address	            Company Address
                        Street      City	State      Street
City
----------------------------------------------------------------------------
----
cust1		Customer 1	  88thStreet Cheyenne CO       128th Street
Bloomfield
 
----------------------------
                                                     16th Street   TeaNeck
----------------------------------------------------------------------------
-
cust2		Customer 2	  Amber St    Madison MI       S.
Hammerfield
                                                        Pkwy       Chicago
 
----------------------------
                                                     16th Street   Madison

Note: This is just a small set, for brevity purpose.  Number of fields to be
displayed in the report could be in the order of 80+.


Current Thread
Keywords