xsl-list
[Top] [All Lists]

Re: Re: XSL to write XML tag values in columns

2003-12-24 03:19:49

"Jaime Stuardo" <jstuardo(_at_)security(_dot_)cl> wrote in message
news:CA4A243A1C219949AABAEBF59C313C3D3ABB59(_at_)srv-security-53(_dot_)(_dot_)(_dot_)
Sorry.. but I forgot to tell 2 things:

1) That XML was only an example. The orifinal XML will be dynamic... so
f_key may have value 1, 2 or n.

2) This is the right structure I want to achieve:

This is just a little bit more complicated.

First we use the Muenchian method to find all different values for f_key.

Then we find the f_key value (from all different such values) that has most
occurences in the xml document.

Then we construct the header row of the table.

Then in a separate named template we construct the remaining rows of the
table.

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:key name="kValByField" match="field"
       use="preceding-sibling::f_key[1]"/>

  <xsl:key name="kByVal" match="f_key" use="."/>

  <xsl:variable name="vAllKeys"
   select="/*/ROW/f_key[generate-id()
                       =
                        generate-id(key('kByVal', .)[1])
                       ]"/>
  <xsl:variable name="vKeyWithMaxMembers">
    <xsl:for-each select="$vAllKeys">
      <xsl:sort select="count(key('kValByField', .))"
      data-type="number" order="descending"/>

      <xsl:if test="position() = 1">
        <xsl:value-of select="."/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:template match="/">
   <table>
     <tr>
       <xsl:for-each select="$vAllKeys">
         <xsl:sort select="." data-type="number"/>
       <td>f_key = <xsl:value-of select="."/></td>
       </xsl:for-each>
     </tr>

    <xsl:call-template name="tableRows">
      <xsl:with-param name="pRows"
       select="key('kValByField', $vKeyWithMaxMembers)"/>
      <xsl:with-param name="pkeyVals" select="$vAllKeys"/>
    </xsl:call-template>
    </table>
  </xsl:template>

  <xsl:template name="tableRows">
      <xsl:param name="pRows"/>
      <xsl:param name="pkeyVals" select="/.."/>

    <xsl:for-each select="$pRows">
      <xsl:variable name="vPos" select="position()"/>
      <tr>
        <xsl:for-each select="$pkeyVals">
          <xsl:sort select="." data-type="number"/>

           <td>
             <xsl:value-of select="key('kValByField', .)[position() =
$vPos]"/>
           </td>
        </xsl:for-each>
      </tr>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

when applied on this source.xml:

<test>
  <ROW>
    <f_key>1</f_key>
    <field>blabla</field>
  </ROW>
  <ROW>
    <f_key>1</f_key>
    <field>bleble</field>
  </ROW>
  <ROW>
    <f_key>3</f_key>
    <field>alabala</field>
  </ROW>
  <ROW>
    <f_key>2</f_key>
    <field>blibli</field>
  </ROW>
  <ROW>
    <f_key>2</f_key>
    <field>bloblo</field>
  </ROW>
  <ROW>
    <f_key>3</f_key>
    <field>tarabara</field>
  </ROW>
  <ROW>
    <f_key>1</f_key>
    <field>bleubleu</field>
  </ROW>
</test>


produces the wanted result:

<table>
   <tr>
      <td>f_key = 1</td>
      <td>f_key = 2</td>
      <td>f_key = 3</td>
   </tr>
   <tr>
      <td>blabla</td>
      <td>blibli</td>
      <td>alabala</td>
   </tr>
   <tr>
      <td>bleble</td>
      <td>bloblo</td>
      <td>tarabara</td>
   </tr>
   <tr>
      <td>bleubleu</td>
      <td/>
      <td/>
   </tr>
</table>


Hope this helped.


Dimitre Novatchev.
FXSL developer

http://fxsl.sourceforge.net/ -- the home of FXSL
Resume: http://fxsl.sf.net/DNovatchev/Resume/Res.html




 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



<Prev in Thread] Current Thread [Next in Thread>