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

RE: [xsl] XSLT 1.0 : HTML table with


Subject: RE: [xsl] XSLT 1.0 : HTML table with
From: jeanph01 <jeanph01@xxxxxxxx>
Date: Thu, 22 Apr 2010 16:07:32 -0400

Thank you for responding.

But I wonder, can I do it in a single xsl file in a single call? Because I
cannot have and intermediate transformation with 2 calls, I have to do it in
one shot. Maybe I do not understand a capability of xsl:copy ?

I managed to get what I wanted in the meantime but i'm not sure if this is the
best solution in term of performance because it will have to go through
$champs for each td:

  <xsl:key name="names" match="*|@*" use="name()"/>
  <xsl:variable name="champs" select="//SearchResult/*[not(.=following::*) and
(generate-id(.) = generate-id(key('names', name(.))[1]))]"></xsl:variable>


  <xsl:template match="/Output/SearchResults">
    <table border="1">
      <thead>
        <tr>
          <xsl:for-each select="$champs">
            <th>
              <xsl:value-of select="local-name()"/>
            </th>
          </xsl:for-each>
        </tr>
      </thead>
      <tbody>
        <xsl:apply-templates/>
      </tbody>
    </table>
  </xsl:template>

  <xsl:template match="SearchResult">
    <xsl:variable name="thisRow" select=".//*"></xsl:variable>
    <tr>
      <xsl:for-each select="$champs">
        <xsl:variable name="thisField" select="local-name(.)"></xsl:variable>
        <td>
          <xsl:text>&#160;</xsl:text>
          <xsl:for-each select="$thisRow">
            <xsl:if test="$thisField = local-name(.)">
              <xsl:value-of select="local-name(.)"/>
              <xsl:text>=</xsl:text>
              <xsl:value-of select="."/>
            </xsl:if>
          </xsl:for-each>
        </td>
      </xsl:for-each>
    </tr>
  </xsl:template>





---- Le jeu., 22 avr. 2010 04:27:37 -0400 Robby Pelssers
<robby.pelssers@xxxxxxxxx> a C)crit ----

 > Sounds easily doable..
 >
 > If you first create the header inside the <output> element in a first
transformation till you get result below
 >
 >  <?xml version="1.0" encoding="ISO-8859-1" ?>
 >  <output>
 >     <thead>
 >       <tr>
 >         <th>OTCreateDate</th>
 >         <th>OTCreatedByFullName</th>
 >         <th>Score</th>
 >         <th>Attr_4539360_16</th>
 >         <th>Attr_4539360_26</th>
 >       </tr>
 >    </thead>
 >    <SearchResults>
 >      <SearchResult>
 >        <OTCreateDate>2009-10-27</OTCreateDate>
 >        <OTCreatedByFullName>Jean-Philippe Martin</OTCreatedByFullName>
 >        <Score>97</Score>
 >      </SearchResult>
 >      <SearchResult>
 >        <Attr_4539360_16>Nord</Attr_4539360_16>
 >        <Attr_4539360_26>TransfC)rer</Attr_4539360_26>
 >        <OTCreateDate >2007-08-30</OTCreateDate>
 >        <OTCreatedByFullName >Caroline</OTCreatedByFullName>
 >        <Score>94</Score>
 >      </SearchResult>
 >    </SearchResults>
 >  </output>
 >
 >
 > Next you process the <output> a second time
 >
 > <?xml version="1.0" encoding="UTF-8"?>
 > <xsl:stylesheet version="1.0"
 >     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
 >     <xsl:output method="xml" version="1.0" encoding="UTF-8"
 >         indent="yes" />
 >
 >     <xsl:variable name="tableHeaders" select="/output/thead/tr/th" />
 >
 >     <xsl:template match="/">
 >         <xsl:apply-templates select="output" />
 >     </xsl:template>
 >
 >     <xsl:template match="output">
 >         <html>
 >             <body>
 >                 <table>
 >                     <xsl:apply-templates select="thead" />
 >                     <xsl:apply-templates select="SearchResults" />
 >                 </table>
 >             </body>
 >         </html>
 >     </xsl:template>
 >
 >     <xsl:template match="SearchResults">
 >         <tbody>
 >             <xsl:apply-templates select="SearchResult" />
 >         </tbody>
 >     </xsl:template>
 >
 >     <xsl:template match="SearchResult">
 >         <xsl:variable name="result" select="." />
 >         <tr>
 >           <xsl:for-each select="$tableHeaders">
 >             <xsl:variable name="header" select="./text()"/>
 >             <td>
 >               <xsl:apply-templates select="$result/*[local-name() =
$header]/text()"/>
 >             </td>
 >           </xsl:for-each>
 >         </tr>
 >     </xsl:template>
 >
 >
 >     <!--
 >         copy all nodes and attributes which are not processed by one of
 >         available templates
 >     -->
 >     <xsl:template match="@*|node()">
 >         <xsl:copy>
 >             <xsl:apply-templates select="@*" />
 >             <xsl:apply-templates />
 >         </xsl:copy>
 >     </xsl:template>
 >
 > </xsl:stylesheet>
 >
 > Cheers,
 > Robby
 >
 > -----Original Message-----
 > From: jeanph01 [mailto:jeanph01@xxxxxxxx]
 > Sent: Wednesday, April 21, 2010 10:19 PM
 > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
 > Subject: [xsl] XSLT 1.0 : HTML table with
 >
 >
 >  I want to create a table with xslt 1.0 from an XML source file containing
a varying number of key for each row :
 >
 >  <?xml version="1.0" encoding="ISO-8859-1" ?>
 >  <output>
 >    <SearchResults>
 >      <SearchResult>
 >        <OTCreateDate>2009-10-27</OTCreateDate>
 >        <OTCreatedByFullName>Jean-Philippe Martin</OTCreatedByFullName>
 >        <Score>97</Score>
 >      </SearchResult>
 >      <SearchResult>
 >        <Attr_4539360_16>Nord</Attr_4539360_16>
 >        <Attr_4539360_26>TransfC)rer</Attr_4539360_26>
 >        <OTCreateDate >2007-08-30</OTCreateDate>
 >        <OTCreatedByFullName >Caroline</OTCreatedByFullName>
 >        <Score>94</Score>
 >      </SearchResult>
 >    </SearchResults>
 >  </output>
 >
 >
 >  So here my first key <SearchResult> have 3 sub-keys. But the second
<SearchResult> key have 5 sub-keys. I don't know what key will be present in
the set since it's a search result.
 >
 >  This would have to give an html which would look like this with 5 columns:
 >
 >  <html>
 >      <body>
 >          <table>
 >              <thead>
 >                  <tr>
 >                      <th>OTCreateDate</th>
 >                      <th>OTCreatedByFullName</th>
 >                      <th>Score</th>
 >                      <th>Attr_4539360_16</th>
 >                      <th>Attr_4539360_26</th>
 >                  </tr>
 >              </thead>
 >              <tbody>
 >                  <tr>
 >                      <td>2009-10-27</td>
 >                      <td>Jean-Philippe Martin</td>
 >                      <td>97</td>
 >                      <td></td>
 >                      <td></td>
 >                  </tr>
 >                  <tr>
 >                      <td>2007-08-30</td>
 >                      <td>Caroline</td>
 >                      <td>94</td>
 >                      <td>Nord</td>
 >                      <td>TransfC)rer</td>
 >                  </tr>
 >              </tbody>
 >          </table>
 >      </body>
 >  </html>
 >
 >
 >  First, can it be done ?
 >
 >  For the head row  I managed to get the unique key names with a M. Kay
algorithm I found but how to link a specific TD to its TH ?
 >
 >    <xsl:template match="/">
 >      <table border="1">
 >        <thead>
 >          <tr>
 >            <xsl:for-each select="//SearchResult/*">
 >              <xsl:sort select="name(.)"/>
 >              <xsl:if test="generate-id(.) = generate-id(key('names',
name(.))[1])">
 >                <th>
 >                  <xsl:value-of select="local-name()"/>
 >                </th>
 >              </xsl:if>
 >            </xsl:for-each>
 >          </tr>
 >        </thead>
 >      </table>
 >    </xsl:template>
 >
 >
 >  Thank you for any help.


Current Thread
Keywords