jantursky
jantursky

Reputation: 1130

Change xml to xhtml through xslt

i'm trying to transform xml file from ECB to xhtml through xslt but i have somewhere mistake.

This is XML file

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="output.xsl"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" 
    xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
    <gesmes:subject>Reference rates</gesmes:subject>
    <gesmes:Sender>
        <gesmes:name>European Central Bank</gesmes:name>
    </gesmes:Sender>
    <Cube>
        <Cube time='2011-10-18'>
            <Cube currency='USD' rate='1.3676'/>
            <Cube currency='JPY' rate='104.97'/>
            <Cube currency='BGN' rate='1.9558'/>
            <Cube currency='CZK' rate='24.925'/>
            <Cube currency='DKK' rate='7.4456'/>
            <Cube currency='GBP' rate='0.87020'/>
            <Cube currency='HUF' rate='298.40'/>
            <Cube currency='LTL' rate='3.4528'/>
            <Cube currency='LVL' rate='0.7057'/>
            <Cube currency='PLN' rate='4.3684'/>
            <Cube currency='RON' rate='4.3525'/>
            <Cube currency='SEK' rate='9.1589'/>
            <Cube currency='CHF' rate='1.2348'/>
            <Cube currency='NOK' rate='7.7605'/>
            <Cube currency='HRK' rate='7.4715'/>
            <Cube currency='RUB' rate='42.8780'/>
            <Cube currency='TRY' rate='2.5568'/>
            <Cube currency='AUD' rate='1.3489'/>
            <Cube currency='BRL' rate='2.4332'/>
            <Cube currency='CAD' rate='1.4018'/>
            <Cube currency='CNY' rate='8.7262'/>
            <Cube currency='HKD' rate='10.6373'/>
            <Cube currency='IDR' rate='12061.31'/>
            <Cube currency='ILS' rate='4.9936'/>
            <Cube currency='INR' rate='67.5500'/>
            <Cube currency='KRW' rate='1567.60'/>
            <Cube currency='MXN' rate='18.5187'/>
            <Cube currency='MYR' rate='4.2854'/>
            <Cube currency='NZD' rate='1.7360'/>
            <Cube currency='PHP' rate='59.256'/>
            <Cube currency='SGD' rate='1.7423'/>
            <Cube currency='THB' rate='42.095'/>
            <Cube currency='ZAR' rate='11.0432'/>
        </Cube>
    </Cube>
</gesmes:Envelope>

and here is my XSLT file

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" encoding="utf-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
 
    <xsl:template match="/">
        <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
            <title>Exchange rates</title>

     </head>

        <body>
            <table>
                <tr>
                    <th>Rate</th>
                </tr>
            <xsl:for-each select="/gesmes:Envelope/Cube/Cube/Cube">
             <tr>
                    <td><xsl:value-of select="Cube/[@currency='USD']"/></td>

                </tr>
                </xsl:for-each>

            </table>
        </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

And result look like this:

USD 1.3676
JPY 104.97
BGN 1.9558

and so on

I need a solution, not a way how to get the right source code.

Upvotes: 0

Views: 2868

Answers (3)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243459

Seems you want something like this (I have just edited your code -- my own solution would be different):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01"
 xmlns:ecb="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
 >
    <xsl:output method="xml" encoding="utf-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
    <xsl:template match="/">
        <html xmlns="http://www.w3.org/1999/xhtml">
            <head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
                <title>Exchange rates</title>
            </head>
            <body>
                <table>
                    <tr>
                        <th>Currency</th>
                        <th>Rate</th>
                    </tr>
                    <xsl:for-each select="/gesmes:Envelope/ecb:Cube/ecb:Cube/ecb:Cube">
                        <tr>
                            <td>
                                <b><xsl:value-of select="@currency"/></b>
                            </td>
                            <td>
                                <xsl:value-of select="@rate"/>
                            </td>
                        </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

When applied on the provided XML document:

<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01"
 xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
    <gesmes:subject>Reference rates</gesmes:subject>
    <gesmes:Sender>
        <gesmes:name>European Central Bank</gesmes:name>
    </gesmes:Sender>
    <Cube>
        <Cube time='2011-10-18'>
            <Cube currency='USD' rate='1.3676'/>
            <Cube currency='JPY' rate='104.97'/>
            <Cube currency='BGN' rate='1.9558'/>
            <Cube currency='CZK' rate='24.925'/>
            <Cube currency='DKK' rate='7.4456'/>
            <Cube currency='GBP' rate='0.87020'/>
            <Cube currency='HUF' rate='298.40'/>
            <Cube currency='LTL' rate='3.4528'/>
            <Cube currency='LVL' rate='0.7057'/>
            <Cube currency='PLN' rate='4.3684'/>
            <Cube currency='RON' rate='4.3525'/>
            <Cube currency='SEK' rate='9.1589'/>
            <Cube currency='CHF' rate='1.2348'/>
            <Cube currency='NOK' rate='7.7605'/>
            <Cube currency='HRK' rate='7.4715'/>
            <Cube currency='RUB' rate='42.8780'/>
            <Cube currency='TRY' rate='2.5568'/>
            <Cube currency='AUD' rate='1.3489'/>
            <Cube currency='BRL' rate='2.4332'/>
            <Cube currency='CAD' rate='1.4018'/>
            <Cube currency='CNY' rate='8.7262'/>
            <Cube currency='HKD' rate='10.6373'/>
            <Cube currency='IDR' rate='12061.31'/>
            <Cube currency='ILS' rate='4.9936'/>
            <Cube currency='INR' rate='67.5500'/>
            <Cube currency='KRW' rate='1567.60'/>
            <Cube currency='MXN' rate='18.5187'/>
            <Cube currency='MYR' rate='4.2854'/>
            <Cube currency='NZD' rate='1.7360'/>
            <Cube currency='PHP' rate='59.256'/>
            <Cube currency='SGD' rate='1.7423'/>
            <Cube currency='THB' rate='42.095'/>
            <Cube currency='ZAR' rate='11.0432'/></Cube></Cube>
</gesmes:Envelope>

the wanted, correct result is produced:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>Exchange rates</title>
    </head>
    <body>
        <table>
            <tr>
                <th>Currency</th>
                <th>Rate</th>
            </tr>
            <tr>
                <td>
                    <b>USD</b>
                </td>
                <td>1.3676</td>
            </tr>
            <tr>
                <td>
                    <b>JPY</b>
                </td>
                <td>104.97</td>
            </tr>
            <tr>
                <td>
                    <b>BGN</b>
                </td>
                <td>1.9558</td>
            </tr>
            <tr>
                <td>
                    <b>CZK</b>
                </td>
                <td>24.925</td>
            </tr>
            <tr>
                <td>
                    <b>DKK</b>
                </td>
                <td>7.4456</td>
            </tr>
            <tr>
                <td>
                    <b>GBP</b>
                </td>
                <td>0.87020</td>
            </tr>
            <tr>
                <td>
                    <b>HUF</b>
                </td>
                <td>298.40</td>
            </tr>
            <tr>
                <td>
                    <b>LTL</b>
                </td>
                <td>3.4528</td>
            </tr>
            <tr>
                <td>
                    <b>LVL</b>
                </td>
                <td>0.7057</td>
            </tr>
            <tr>
                <td>
                    <b>PLN</b>
                </td>
                <td>4.3684</td>
            </tr>
            <tr>
                <td>
                    <b>RON</b>
                </td>
                <td>4.3525</td>
            </tr>
            <tr>
                <td>
                    <b>SEK</b>
                </td>
                <td>9.1589</td>
            </tr>
            <tr>
                <td>
                    <b>CHF</b>
                </td>
                <td>1.2348</td>
            </tr>
            <tr>
                <td>
                    <b>NOK</b>
                </td>
                <td>7.7605</td>
            </tr>
            <tr>
                <td>
                    <b>HRK</b>
                </td>
                <td>7.4715</td>
            </tr>
            <tr>
                <td>
                    <b>RUB</b>
                </td>
                <td>42.8780</td>
            </tr>
            <tr>
                <td>
                    <b>TRY</b>
                </td>
                <td>2.5568</td>
            </tr>
            <tr>
                <td>
                    <b>AUD</b>
                </td>
                <td>1.3489</td>
            </tr>
            <tr>
                <td>
                    <b>BRL</b>
                </td>
                <td>2.4332</td>
            </tr>
            <tr>
                <td>
                    <b>CAD</b>
                </td>
                <td>1.4018</td>
            </tr>
            <tr>
                <td>
                    <b>CNY</b>
                </td>
                <td>8.7262</td>
            </tr>
            <tr>
                <td>
                    <b>HKD</b>
                </td>
                <td>10.6373</td>
            </tr>
            <tr>
                <td>
                    <b>IDR</b>
                </td>
                <td>12061.31</td>
            </tr>
            <tr>
                <td>
                    <b>ILS</b>
                </td>
                <td>4.9936</td>
            </tr>
            <tr>
                <td>
                    <b>INR</b>
                </td>
                <td>67.5500</td>
            </tr>
            <tr>
                <td>
                    <b>KRW</b>
                </td>
                <td>1567.60</td>
            </tr>
            <tr>
                <td>
                    <b>MXN</b>
                </td>
                <td>18.5187</td>
            </tr>
            <tr>
                <td>
                    <b>MYR</b>
                </td>
                <td>4.2854</td>
            </tr>
            <tr>
                <td>
                    <b>NZD</b>
                </td>
                <td>1.7360</td>
            </tr>
            <tr>
                <td>
                    <b>PHP</b>
                </td>
                <td>59.256</td>
            </tr>
            <tr>
                <td>
                    <b>SGD</b>
                </td>
                <td>1.7423</td>
            </tr>
            <tr>
                <td>
                    <b>THB</b>
                </td>
                <td>42.095</td>
            </tr>
            <tr>
                <td>
                    <b>ZAR</b>
                </td>
                <td>11.0432</td>
            </tr>
        </table>
    </body>
</html>

My own solutions would be more like this:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01"
 xmlns:ecb="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
 exclude-result-prefixes="ecb gesmes">
    <xsl:output method="xml" encoding="utf-8"
     doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
     doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>

    <xsl:strip-space elements="*"/>

    <xsl:template match="ecb:Cube/ecb:Cube">
        <html xmlns="http://www.w3.org/1999/xhtml">
            <head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
                <title>Exchange rates</title>
            </head>
            <body>
                <table>
                    <tr>
                        <th>Currency</th>
                        <th>Rate</th>
                    </tr>
                 <xsl:apply-templates/>
                </table>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="ecb:Cube/ecb:Cube/ecb:Cube" priority="5">
            <tr>
                <td>
                    <b><xsl:value-of select="@currency"/></b>
                </td>
                <td>
                    <xsl:value-of select="@rate"/>
                </td>
            </tr>
    </xsl:template>
    <xsl:template match="text()"/>
</xsl:stylesheet>

Upvotes: 0

Kirill Polishchuk
Kirill Polishchuk

Reputation: 56162

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"
                xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01">
    <xsl:output method="html" encoding="utf-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
                doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>


    <xsl:template match="/">
        <html xmlns="http://www.w3.org/1999/xhtml">
            <head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
                <title>Exchange rates</title>
            </head>

            <body>
                <table>
                    <tr>
                        <th>Rate</th>
                        <th>Value</th>
                    </tr>
                    <xsl:apply-templates select="//ns:Cube/ns:Cube"/>


                </table>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="ns:Cube">
        <tr xmlns="http://www.w3.org/1999/xhtml">
            <td>
                <xsl:value-of select="@currency"/>
            </td>
            <td>
                <xsl:value-of select="@rate"/>
            </td>
        </tr>
    </xsl:template>

</xsl:stylesheet>

Output:

Rate Value 
USD 1.3676 
JPY 104.97 
BGN 1.9558 
CZK 24.925 
DKK 7.4456 
GBP 0.8702 
HUF 298.4 
LTL 3.4528 
LVL 0.7057 
PLN 4.3684 
RON 4.3525 
SEK 9.1589 
CHF 1.2348 
NOK 7.7605 
HRK 7.4715 
RUB 42.878 
TRY 2.5568 
AUD 1.3489 
BRL 2.4332 
CAD 1.4018 
CNY 8.7262 
HKD 10.6373 
IDR 12061.31 
ILS 4.9936 
INR 67.55 
KRW 1567.6 
MXN 18.5187 
MYR 4.2854 
NZD 1.736 
PHP 59.256 
SGD 1.7423 
THB 42.095 
ZAR 11.0432 

Upvotes: 0

boblemar
boblemar

Reputation: 1153

OK ! I didn't saw.

Your major problem is a namespace one : XSLT engine doesn't know what is gesmes, so you need to tell it. So you need to add it in your xsl:stylesheet tag.

  • xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01"

You need to add and name a namespace for the default namespace of your xml :

  • xmlns:xx="http://www.ecb.int/vocabulary/2002-08-01/eurofxref" so your stylesheet will start with :

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns:xx="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">

your for-each will be : <xsl:for-each select="/gesmes:Envelope/xx:Cube/xx:Cube/xx:Cube">

And it should work... but I suggest you use a template in place of xsl:for-each

Here is the solution I propose : OK ! I didn't saw.

Your major problem is a namespace one : XSLT engine doesn't know what is gesmes, so you need to tell it. So you need to add it in your xsl:stylesheet tag.

  • xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01"

You need to add and name a namespace for the default namespace of your xml :

  • xmlns:xx="http://www.ecb.int/vocabulary/2002-08-01/eurofxref" so your stylesheet will start with :

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns:xx="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">

your for-each will be : <xsl:for-each select="/gesmes:Envelope/xx:Cube/xx:Cube/xx:Cube">

And it should work... but I suggest you use a template in place of xsl:for-each

Here is the solution I propose :

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01"
                xmlns:xx="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
<xsl:output method="html" encoding="utf-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:template match="/">
  <html xmlns="http://www.w3.org/1999/xhtml">
    <body>
      <table>
        <tr><th>Rate</th></tr>
        <xsl:apply-templates select="gesmes:Envelope/xx:Cube/xx:Cube/xx:Cube" />
      </table>
    </body>
  </html>
</xsl:template>

<xsl:template match="xx:Cube">
  <tr>
    <td><xsl:value-of select="@currency"/></td>
    <td><xsl:value-of select="@rate"/></td>
  </tr>
</xsl:template>
</xsl:stylesheet>

Upvotes: 1

Related Questions