RE: [xsl] Question on loops

Subject: RE: [xsl] Question on loops
From: "M. David Peterson" <m.david@xxxxxxxxxx>
Date: Mon, 22 Mar 2004 17:21:22 -0700
For positional grouping like this my favorite method is first creating
an RTF that is pre-sorted into the proper groups and then converting it
to a node-set(I'm using Xalan at the moment but most processors have
some form of a node-set function) that I can then use standard
apply-templates to transform.  I also prefer to avoid for-each loops
when transforming the data into columns, especially when the number of
columns can vary.  Although the code can be longer it gives you much
more control over the layout of each individual element and separates
the code into "objects" that are simpler to manage and make changes to.
It also conforms to the functional method of letting the data drive the
transformation.  This entire stylesheet uses one conditional if
statement to determine when to begin a new row of columns.  The rest of
the "decision" making is left up to the XML driving the transformation.


I just copied and pasted your element names into a template I already
had laying around that allows you to change the number of columns you
want your data sorted into (I made a few tweaks but nothing major.)
Thus you probably got more than what you were expecting on this one but
if this helps you I am more than happy to pass along the knowledge.

Have a great day!

<M:D/>

This XML >>

<?xml version="1.0" encoding="UTF-8"?>
<DBInspector ReportName="Query Report" Date="15.01.2004">
	<SQLStatement>select * from testdb2.person p, testdb2.adresse a
where 
p.persnr = a.persnr</SQLStatement>
	<ColumnNames>
		<Column>persnr</Column>
		<Column>name</Column>
		<Column>vorname</Column>
		<Column>nr</Column>
	</ColumnNames>
	<ColumnEntries>
		<Row>
			<Entrie type="Integer">1</Entrie>
			<Entrie type="Variable
Character">Wehnert</Entrie>
			<Entrie type="Variable
Character">Lothar</Entrie>
			<Entrie type="Variable Character">Yoyo</Entrie>
			<Entrie type="Variable
Character">Lothar</Entrie>
		</Row>
		<Row>
			<Entrie type="Integer">2</Entrie>
			<Entrie type="Variable Character">Egg</Entrie>
			<Entrie type="Variable Character">Loth</Entrie>
			<Entrie type="Variable Character">Was</Entrie>
			<Entrie type="Variable Character">Ertz</Entrie>
		</Row>
	</ColumnEntries>
</DBInspector>

Processed by this XSLT >>

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:xalan="http://xml.apache.org/xalan";
                version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output method="html" indent="yes" encoding="iso-8859-1"/>

<xsl:variable name="number_of_columns">2</xsl:variable>

<xsl:template match="/">
  <xsl:variable name="groupedContent">
  <xsl:copy>
    <Columns>
      <xsl:apply-templates select="/DBInspector/ColumnNames/Column">
        <xsl:with-param name="matchingEntrie"
select="DBInspector/ColumnEntries/Row"/>
      </xsl:apply-templates>
    </Columns>
  </xsl:copy>
  </xsl:variable>
  <xsl:call-template name="transform">
    <xsl:with-param name="groupedContent"
select="xalan:nodeset($groupedContent)"/>
  </xsl:call-template>
</xsl:template>

<xsl:template match="Column">
  <xsl:param name="matchingEntrie"/>
  <xsl:variable name="pos" select="position()"/>
    <xsl:copy>
      <xsl:attribute name="name"><xsl:value-of
select="."/></xsl:attribute>
      <xsl:copy-of select="$matchingEntrie/Entrie[position() = $pos]"/>
    </xsl:copy>
</xsl:template>

<xsl:template name="transform">
  <xsl:param name="groupedContent"/>
  <table>
    <xsl:apply-templates select="$groupedContent/Columns/Column"
mode="transform"/>
  </table>
</xsl:template>

<xsl:template match="Column" mode="transform">
<xsl:variable name="pos" select="position()"/>
  <xsl:if test="(($pos - 1) mod $number_of_columns) = 0">
    <tr>
      <xsl:apply-templates select=". |
following-sibling::Column[position() &lt; ($pos + ($number_of_columns -
1))]" mode="row"/>
    </tr>
  </xsl:if>
</xsl:template>

<xsl:template match="Column" mode="row">
  <td>
    <table>
      <tr>
        <td>
          <xsl:value-of select="@name"/>
        </td>
      </tr>
      <tr>
        <td>
	    <!-- this value-of translates the name of column into dashes
which allows you to control the length of your dashed line more
precisely to the length of the data -->
          <xsl:value-of select="translate(@name,
'abcdefghijklmnopqrstuvwxyz', '--------------------------')"/>
        </td>
      </tr>
      <xsl:apply-templates select="Entrie"/>
    </table>
  </td>
</xsl:template>

<xsl:template match="Entrie">
  <tr>
    <td>
      <xsl:value-of select="."/>
    </td>
  </tr>
</xsl:template>

</xsl:stylesheet>

Gives you this HTML >>

<table>
  <tr>
    <td>
      <table>
        <tr>
          <td>persnr</td>
        </tr>
        <tr>
          <td>------</td>
        </tr>
        <tr>
          <td>1</td>
        </tr>
        <tr>
          <td>2</td>
        </tr>
      </table>
    </td><td>
      <table>
        <tr>
          <td>name</td>
        </tr>
        <tr>
          <td>----</td>
        </tr>
        <tr>
          <td>Wehnert</td>
        </tr>
        <tr>
          <td>Egg</td>
        </tr>
      </table>
    </td>
  </tr>
  <tr>
    <td>
      <table>
        <tr>
          <td>vorname</td>
        </tr>
        <tr>
          <td>-------</td>
        </tr>
        <tr>
          <td>Lothar</td>
        </tr>
        <tr>
          <td>Loth</td>
        </tr>
      </table>
    </td><td>
      <table>
        <tr>
          <td>nr</td>
        </tr>
        <tr>
          <td>--</td>
        </tr>
        <tr>
          <td>Yoyo</td>
        </tr>
        <tr>
          <td>Was</td>
        </tr>
      </table>
    </td>
  </tr>
</table>

-----Original Message-----
From: Jonny Pony [mailto:jonnypony666@xxxxxxxxxxx] 
Sent: Monday, March 22, 2004 10:32 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: [xsl] Question on loops

Hi,

I have an XML-file like this:

<?xml version="1.0" encoding="UTF-8"?>
<DBInspector ReportName="Query Report" Date="15.01.2004">
	<SQLStatement>select * from testdb2.person p, testdb2.adresse a
where 
p.persnr = a.persnr</SQLStatement>
	<ColumnNames>
		<Column>persnr</Column>
		<Column>name</Column>
		<Column>vorname</Column>
		<Column>nr</Column>
		...
	</ColumnNames>
	<ColumnEntries>
		<Row>
			<Entrie type="Integer">1</Entrie>
			<Entrie type="Variable
Character">Wehnert</Entrie>
			<Entrie type="Variable
Character">Lothar</Entrie>
			<Entrie type="Variable Character">Yoyo</Entrie>
			<Entrie type="Variable
Character">Lothar</Entrie>
			...
		</Row>
		<Row>
			<Entrie type="Integer">2</Entrie>
			<Entrie type="Variable Character">Egg</Entrie>
			<Entrie type="Variable Character">Loth</Entrie>
			<Entrie type="Variable Character">Was</Entrie>
			<Entrie type="Variable Character">Ertz</Entrie>
			...
		</Row>
		...

My aim is to create a table after e.g. every second column.

Something like this:

persnr   name
----------------
1        Wehnert
2        Egg


vorname  nr
----------------
Yoyo     Lothar
Was      Ertz


Unfortunately I cannot change the structure of the XML-file, therefore I

have no clue how to solve this problem.
How can I create a  loop around <ColumnNames> and <ColumnEntries> ?
Anyone got an idea?

Thanks
Jonny

_________________________________________________________________
MSN Messenger - sehen, welche Freunde online sind! 
http://www.msn.de/messenger Jetzt kostenlos downloaden und mitmachen!

Current Thread