Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   XML (http://www.velocityreviews.com/forums/f32-xml.html)
-   -   XSLT to HTML table problem (http://www.velocityreviews.com/forums/t735299-xslt-to-html-table-problem.html)

kanpeter 10-12-2010 03:00 PM

XSLT to HTML table problem
 
given an xml file:
<data>
<invoices>
<invoice type="A">111</invoice>
<invoice type="B">222</invoice>
<invoice type="C">333</invoice>
</invoices>
<invoices>
<invoice type="C">444</invoice>
<invoice type="B">555</invoice>
<invoice type="A">666</invoice>
</invoices>
<invoices>
<invoice type="C">777</invoice>
<invoice type="A">999</invoice>
</invoices>
</data>

how can i write an xslt to output the following?

<table border="1">
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
</tr>
<tr>
<td>666</td>
<td>555</td>
<td>444</td>
</tr>
<tr>
<td>999</td>
<td>--</td>
<td>777</td>
</tr>
</table>

Martin Honnen 10-12-2010 03:50 PM

Re: XSLT to HTML table problem
 
kanpeter wrote:
> given an xml file:
> <data>
> <invoices>
> <invoice type="A">111</invoice>
> <invoice type="B">222</invoice>
> <invoice type="C">333</invoice>
> </invoices>
> <invoices>
> <invoice type="C">444</invoice>
> <invoice type="B">555</invoice>
> <invoice type="A">666</invoice>
> </invoices>
> <invoices>
> <invoice type="C">777</invoice>
> <invoice type="A">999</invoice>
> </invoices>
> </data>
>
> how can i write an xslt to output the following?
>
> <table border="1">
> <tr>
> <th>A</th>
> <th>B</th>
> <th>C</th>
> </tr>
> <tr>
> <td>111</td>
> <td>222</td>
> <td>333</td>
> </tr>
> <tr>
> <td>666</td>
> <td>555</td>
> <td>444</td>
> </tr>
> <tr>
> <td>999</td>
> <td>--</td>
> <td>777</td>
> </tr>
> </table>


Here is an XSLT 2.0 stylesheet that should do the job (assuming the
first "invoices" element has the complete set of "type" values (e.g. A,
B, C) you want to output):

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">

<xsl:output method="html" indent="yes"/>

<xsl:key name="k1" match="invoices/invoice" use="@type"/>

<xsl:template match="data">
<table border="1">
<xsl:variable name="types" as="xs:string*"
select="invoices[1]/invoice/@type"/>
<thead>
<tr>
<xsl:for-each select="$types">
<th>
<xsl:value-of select="."/>
</th>
</xsl:for-each>
</tr>
</thead>
<tbody>
<xsl:for-each select="invoices">
<tr>
<xsl:variable name="ci" as="element(invoices)" select="."/>
<xsl:for-each select="$types">
<td>
<xsl:value-of select="if (key('k1', ., $ci)) then
key('k1', ., $ci) else '--'"/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:template>

</xsl:stylesheet>

You can run XSLT 2.0 with Saxon 9 (http://saxon.sourceforge.net),
AltovaXML Tools (http://www.altova.com/altovaxml.html), XQSharp
(http://www.xqsharp.com/) and some other processors (Intel, IBM).


--

Martin Honnen
http://msmvps.com/blogs/martin_honnen/

kanpeter 10-12-2010 04:31 PM

Re: XSLT to HTML table problem
 
On Oct 12, 11:50*pm, Martin Honnen <mahotr...@yahoo.de> wrote:
> kanpeter wrote:
> > given an xml file:
> > <data>
> > * *<invoices>
> > * * * <invoice type="A">111</invoice>
> > * * * <invoice type="B">222</invoice>
> > * * * <invoice type="C">333</invoice>
> > * *</invoices>
> > * *<invoices>
> > * * * <invoice type="C">444</invoice>
> > * * * <invoice type="B">555</invoice>
> > * * * <invoice type="A">666</invoice>
> > * *</invoices>
> > * *<invoices>
> > * * * <invoice type="C">777</invoice>
> > * * * <invoice type="A">999</invoice>
> > * *</invoices>
> > </data>

>
> > how can i write an xslt to output the following?

>
> > <table border="1">
> > * * * <tr>
> > * * * * *<th>A</th>
> > * * * * *<th>B</th>
> > * * * * *<th>C</th>
> > * * * </tr>
> > * * * <tr>
> > * * * * *<td>111</td>
> > * * * * *<td>222</td>
> > * * * * *<td>333</td>
> > * * * </tr>
> > * * * <tr>
> > * * * * *<td>666</td>
> > * * * * *<td>555</td>
> > * * * * *<td>444</td>
> > * * * </tr>
> > * * * <tr>
> > * * * * *<td>999</td>
> > * * * * *<td>--</td>
> > * * * * *<td>777</td>
> > * * * </tr>
> > </table>

>
> Here is an XSLT 2.0 stylesheet that should do the job (assuming the
> first "invoices" element has the complete set of "type" values (e.g. A,
> B, C) you want to output):
>
> <xsl:stylesheet
> * *xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> * *version="2.0"
> * *xmlns:xs="http://www.w3.org/2001/XMLSchema"
> * *exclude-result-prefixes="xs">
>
> * *<xsl:output method="html" indent="yes"/>
>
> * *<xsl:key name="k1" match="invoices/invoice" use="@type"/>
>
> * *<xsl:template match="data">
> * * *<table border="1">
> * * * *<xsl:variable name="types" as="xs:string*"
> select="invoices[1]/invoice/@type"/>
> * * * *<thead>
> * * * * *<tr>
> * * * * * *<xsl:for-each select="$types">
> * * * * * * *<th>
> * * * * * * * *<xsl:value-of select="."/>
> * * * * * * *</th>
> * * * * * *</xsl:for-each>
> * * * * *</tr>
> * * * *</thead>
> * * * *<tbody>
> * * * * *<xsl:for-each select="invoices">
> * * * * * *<tr>
> * * * * * * *<xsl:variable name="ci" as="element(invoices)" select="."/>
> * * * * * * *<xsl:for-each select="$types">
> * * * * * * * *<td>
> * * * * * * * * *<xsl:value-of select="if (key('k1', .., $ci)) then
> key('k1', ., $ci) else '--'"/>
> * * * * * * * *</td>
> * * * * * * *</xsl:for-each>
> * * * * * *</tr>
> * * * * *</xsl:for-each>
> * * * *</tbody>
> * * *</table>
> * *</xsl:template>
>
> </xsl:stylesheet>
>
> You can run XSLT 2.0 with Saxon 9 (http://saxon.sourceforge.net),
> AltovaXML Tools (http://www.altova.com/altovaxml.html), XQSharp
> (http://www.xqsharp.com/) and some other processors (Intel, IBM).
>
> --
>
> * * * * Martin Honnen
> * * * *http://msmvps.com/blogs/martin_honnen/


Actually, i want to make the table header contains sorted distinct
values of attribute "type" of element invoice.

kanpeter 10-12-2010 04:33 PM

Re: XSLT to HTML table problem
 
On Oct 13, 12:31*am, kanpeter <kanchun...@gmail.com> wrote:
> On Oct 12, 11:50*pm, Martin Honnen <mahotr...@yahoo.de> wrote:
>
>
>
> > kanpeter wrote:
> > > given an xml file:
> > > <data>
> > > * *<invoices>
> > > * * * <invoice type="A">111</invoice>
> > > * * * <invoice type="B">222</invoice>
> > > * * * <invoice type="C">333</invoice>
> > > * *</invoices>
> > > * *<invoices>
> > > * * * <invoice type="C">444</invoice>
> > > * * * <invoice type="B">555</invoice>
> > > * * * <invoice type="A">666</invoice>
> > > * *</invoices>
> > > * *<invoices>
> > > * * * <invoice type="C">777</invoice>
> > > * * * <invoice type="A">999</invoice>
> > > * *</invoices>
> > > </data>

>
> > > how can i write an xslt to output the following?

>
> > > <table border="1">
> > > * * * <tr>
> > > * * * * *<th>A</th>
> > > * * * * *<th>B</th>
> > > * * * * *<th>C</th>
> > > * * * </tr>
> > > * * * <tr>
> > > * * * * *<td>111</td>
> > > * * * * *<td>222</td>
> > > * * * * *<td>333</td>
> > > * * * </tr>
> > > * * * <tr>
> > > * * * * *<td>666</td>
> > > * * * * *<td>555</td>
> > > * * * * *<td>444</td>
> > > * * * </tr>
> > > * * * <tr>
> > > * * * * *<td>999</td>
> > > * * * * *<td>--</td>
> > > * * * * *<td>777</td>
> > > * * * </tr>
> > > </table>

>
> > Here is an XSLT 2.0 stylesheet that should do the job (assuming the
> > first "invoices" element has the complete set of "type" values (e.g. A,
> > B, C) you want to output):

>
> > <xsl:stylesheet
> > * *xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> > * *version="2.0"
> > * *xmlns:xs="http://www.w3.org/2001/XMLSchema"
> > * *exclude-result-prefixes="xs">

>
> > * *<xsl:output method="html" indent="yes"/>

>
> > * *<xsl:key name="k1" match="invoices/invoice" use="@type"/>

>
> > * *<xsl:template match="data">
> > * * *<table border="1">
> > * * * *<xsl:variable name="types" as="xs:string*"
> > select="invoices[1]/invoice/@type"/>
> > * * * *<thead>
> > * * * * *<tr>
> > * * * * * *<xsl:for-each select="$types">
> > * * * * * * *<th>
> > * * * * * * * *<xsl:value-of select="."/>
> > * * * * * * *</th>
> > * * * * * *</xsl:for-each>
> > * * * * *</tr>
> > * * * *</thead>
> > * * * *<tbody>
> > * * * * *<xsl:for-each select="invoices">
> > * * * * * *<tr>
> > * * * * * * *<xsl:variable name="ci" as="element(invoices)" select="."/>
> > * * * * * * *<xsl:for-each select="$types">
> > * * * * * * * *<td>
> > * * * * * * * * *<xsl:value-of select="if (key('k1', ., $ci)) then
> > key('k1', ., $ci) else '--'"/>
> > * * * * * * * *</td>
> > * * * * * * *</xsl:for-each>
> > * * * * * *</tr>
> > * * * * *</xsl:for-each>
> > * * * *</tbody>
> > * * *</table>
> > * *</xsl:template>

>
> > </xsl:stylesheet>

>
> > You can run XSLT 2.0 with Saxon 9 (http://saxon.sourceforge.net),
> > AltovaXML Tools (http://www.altova.com/altovaxml.html), XQSharp
> > (http://www.xqsharp.com/) and some other processors (Intel, IBM).

>
> > --

>
> > * * * * Martin Honnen
> > * * * *http://msmvps.com/blogs/martin_honnen/

>
> Actually, i want to make the table header contains sorted distinct
> values of attribute "type" of element invoice.


Actually, i want to make the table header contains sorted distinct
values of attribute "type" of element invoice and the first invoice
element not necessarily contain all distinct values of "type".

Martin Honnen 10-12-2010 04:53 PM

Re: XSLT to HTML table problem
 
kanpeter wrote:

> Actually, i want to make the table header contains sorted distinct
> values of attribute "type" of element invoice and the first invoice
> element not necessarily contain all distinct values of "type".


Then change the template as follows:

<xsl:template match="data">
<table border="1">
<xsl:variable name="types" as="xs:string*">
<xsl:perform-sort
select="distinct-values(invoices/invoice/@type/xs:string(.))">
<xsl:sort select="."/>
</xsl:perform-sort>
</xsl:variable>
<thead>
<tr>
<xsl:for-each select="$types">
<th>
<xsl:value-of select="."/>
</th>
</xsl:for-each>
</tr>
</thead>
<tbody>
<xsl:for-each select="invoices">
<tr>
<xsl:variable name="ci" as="element(invoices)" select="."/>
<xsl:for-each select="$types">
<td>
<xsl:value-of select="if (key('k1', ., $ci)) then
key('k1', ., $ci) else '--'"/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:template>


--

Martin Honnen
http://msmvps.com/blogs/martin_honnen/

Martin Honnen 10-15-2010 02:24 PM

Re: XSLT to HTML table problem
 
kanpeter wrote:

> Why do i need to use exclude-result-prefixes="xs" ?


With XSLT 2.0 you often use the XML schema namespace
http://www.w3.org/2001/XMLSchema and associate it with the prefix "xs".
If you don't want it to be output on literal result elements you need to
use exclude-result-prefixes="xs", as you need to do for other prefixes
(besides the prefix associated with the XSLT namespace
http://www.w3.org/1999/XSL/Transform that is automatically excluded).

--

Martin Honnen
http://msmvps.com/blogs/martin_honnen/


All times are GMT. The time now is 09:12 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.