XSLT question

B

bobiron

Hi, any ideas to improve the above ugly and not efficient code?
Thanks
Roberto

<!-- source XML
NOTE: elements "col" changes from source to source
-->
<?xml version="1.0"?>
<resultset>
<header>
<col name="#" path="position()" />
<col name="NAME" path="@NAME"/>
<col nome="field 1" path="FIELD_1/text()" />
<col nome="field 2" path="FIELD_2/text()" />
</header>
<items>
<item NAME="name1">
<FIELD_1>8</FIELD_1>
<FIELD_2>5</FIELD_2>
<FIELD_3 />
</item>
<item NAME="name2">
<FIELD_1>9</FIELD_1>
<FIELD_2>4</FIELD_2>
<FIELD_3 />
</item>
</items>
</resultset>

<!-- XSL -->
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head/>
<body>
<table border="1">
<tr>
<xsl:for-each select="resultset/header/col">
<th><xsl:value-of select="@name"/></th>
</xsl:for-each>
</tr>
<xsl:for-each select="resultset/items/item">
<tr>
<th><xsl:value-of select="position()"/></th>
<xsl:variable name="v_item" select="."/>
<xsl:for-each select="/resultset/header/col">
<xsl:choose>
<xsl:when test="@path = '@NAME'" >
<td><xsl:value-of select="$v_item/@NAME"/></td>
</xsl:when>
<xsl:when test="@path = 'FIELD_1/text()'">
<td><xsl:value-of select="$v_item/FIELD_1/text()"/></td>
</xsl:when>
<xsl:when test="@path = 'FIELD_2/text()'">
<td><xsl:value-of select="$v_item/FIELD_2/text()"/></td>
</xsl:when>
<xsl:when test="@path = 'FIELD_3/text()'">
<td><xsl:value-of select="$v_item/FIELD_3/text()"/></td>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
 
M

Magnus Henriksson

bobiron said:
Hi, any ideas to improve the above ugly and not efficient code?
Thanks
Roberto


-- source --

<?xml version="1.0"?>
<resultset>
<header>
<col name="#" path="position()" />
<col name="NAME" path="@NAME"/>
<col name="field 1" path="FIELD_1/text()" />
<col name="field 2" path="FIELD_2/text()" />
</header>
<items>
<item NAME="name1">
<FIELD_1>F11</FIELD_1>
<FIELD_2>F21</FIELD_2>
<FIELD_3>F31</FIELD_3>
</item>
<item NAME="name2">
<FIELD_1>F12</FIELD_1>
<FIELD_2>F22</FIELD_2>
<FIELD_3>F32</FIELD_3>
</item>
<item>
<FIELD_1>F13</FIELD_1>
<FIELD_2>F23</FIELD_2>
<FIELD_4>F43</FIELD_4>
</item>
</items>
</resultset>


-- transform --

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

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

<xsl:template match="resultset">
<table border="1">
<xsl:apply-templates/>
</table>
</xsl:template>

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

<xsl:template match="col">
<th>
<xsl:value-of select="@name"/>
</th>
</xsl:template>

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

<xsl:template match="item">
<tr>
<th>
<xsl:value-of select="count(preceding-sibling::*) + 1"/>
</th>
<td>
<!-- We need this cell whether @NAME is present or not -->
<xsl:value-of select="@NAME"/>
</td>
<!-- Assumes that the names of children are unknown -->
<xsl:apply-templates select="*"/>
</tr>
</xsl:template>

<!-- Assumes that the names of children are unknown -->
<xsl:template match="item/*">
<!-- Check that there is a col element whose @path begins with the name
of the current item/* -->
<xsl:if test="//col[starts-with(@path, name(current()))]">
<td>
<!-- The @path of the col element is not evaluated. To do this
we need
to use extension functions or make two XSLT passes. -->
<xsl:apply-templates/>
</td>
</xsl:if>
</xsl:template>

</xsl:stylesheet>


-- result --

<html>
<head>
<META http-equiv="Content-Type" content="text/html;
charset=UTF-8"></head>
<body>
<table border="1">

<tr>

<th>#</th>
<th>NAME</th>
<th>field 1</th>
<th>field 2</th>

</tr>


<tr>
<th>1</th>
<td>name1</td>
<td>F11</td>
<td>F21</td>
</tr>

<tr>
<th>2</th>
<td>name2</td>
<td>F12</td>
<td>F22</td>
</tr>

<tr>
<th>3</th>
<td></td>
<td>F13</td>
<td>F23</td>
</tr>


</table>
</body>
</html>
 
P

p.lepin

bobiron said:
Hi, any ideas to improve the above ugly and not efficient
code?

[ugly XSLT]

I'm not sure about efficiency, but yes, it is ugly. I would
do something like:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:eek:utput method="xml"/>
<xsl:template match="/">
<xsl:variable
name="header"
select="resultset/header/col"/>
<html>
<body>
<table>
<thead>
<xsl:apply-templates
select="$header"
mode="header"/>
</thead>
<tbody>
<xsl:apply-templates
select="resultset/items/item"
mode="items">
<xsl:with-param
name="format"
select="$header"/>
</xsl:apply-templates>
</tbody>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="col" mode="header">
<th>
<xsl:value-of select="@name"/>
</th>
</xsl:template>
<xsl:template match="col" mode="item">
<xsl:param name="data"/>
<xsl:param name="pos"/>
<td>
<xsl:choose>
<xsl:when test="@path='position()'">
<xsl:value-of select="$pos"/>
</xsl:when>
<xsl:when test="starts-with(@path,'@')">
<xsl:value-of
select=
"
$data/@*
[
name()=substring-after(current()/@path,'@')
]
"/>
</xsl:when>
<xsl:when test="substring-after(@path,'/')='text()'">
<xsl:value-of
select=
"
$data/*
[
name()=substring-before(current()/@path,'/')
]
"/>
</xsl:when>
</xsl:choose>
</td>
</xsl:template>
<xsl:template match="item" mode="items">
<xsl:param name="format"/>
<tr>
<xsl:apply-templates
select="$format"
mode="item">
<xsl:with-param name="data" select="."/>
<xsl:with-param name="pos" select="position()"/>
</xsl:apply-templates>
</tr>
</xsl:template>
</xsl:stylesheet>
 
B

bobiron

With a very little changes, a friend of mine, have found this
solution. I guess a nice solution!

xml:

<?xml version="1.0"?>
<resultset>
<header>
<col name="#" path="position()" />
<col name="NAME" path="NAME"/>
<col name="field 1" path="FIELD_1" />
<col name="field 2" path="FIELD_2" />
</header>
<items>
<item NAME="name1">
<FIELD_1>F11</FIELD_1>
<FIELD_2>F21</FIELD_2>
<FIELD_3>F31</FIELD_3>
</item>
<item NAME="name2">
<FIELD_1>F12</FIELD_1>
<FIELD_2>F22</FIELD_2>
<FIELD_3>F32</FIELD_3>
</item>
<item NAME="name3">
<FIELD_1>F13</FIELD_1>
<FIELD_2>F23</FIELD_2>
<FIELD_4>F43</FIELD_4>
</item>
</items>
</resultset>

xsl:

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

<xsl:template match="/">
<html>
<body>
<table border="1">
<tr>
<xsl:for-each select="resultset/header/col">
<th><xsl:value-of select="@name"/></th>
</xsl:for-each>
</tr>
<xsl:for-each select="resultset/items/item">
<tr>
<xsl:variable name="row" select="."/>
<th><xsl:value-of select="position()"/></th>
<xsl:for-each select="/resultset/header/col">
<xsl:variable name="xpath" select="@path"/>
<xsl:if test="$xpath != 'position()'" >
<td><xsl:value-of select="($row/* | $row/@*)[name() =
$xpath]"/></td>
</xsl:if>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Regards, Roberto
 
P

p.lepin

bobiron said:
With a very little changes, a friend of mine, have found
this solution. I guess a nice solution!
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
<body>
<table border="1">
<tr>
<xsl:for-each select="resultset/header/col">
<th><xsl:value-of select="@name"/></th>
</xsl:for-each>
</tr>
<xsl:for-each select="resultset/items/item">
<tr>
<xsl:variable name="row" select="."/>
<th><xsl:value-of select="position()"/></th>
<xsl:for-each select="/resultset/header/col">
<xsl:variable name="xpath" select="@path"/>
<xsl:if test="$xpath != 'position()'" >
<td><xsl:value-of select="($row/* | $row/@*)
[name() = $xpath]"/></td>
</xsl:if>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Whatever floats your boat, but I'd say you were asking
your question on the wrong newsgroup then. That would be
more appropriate in alt.write.only.code.bork.bork.bork or
something like that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top