#xml #parsing #xslt #xhtml
#xml #синтаксический анализ #xslt #xhtml
Вопрос:
я пытаюсь преобразовать XML-файл из ECB в xhtml через xslt, но у меня где-то ошибка.
Это XML-файл
<?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>
и вот мой файл XSLT
<?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>
И результат выглядит так:
USD 1.3676
JPY 104.97
BGN 1.9558
и так далее
Мне нужно решение, а не способ получить правильный исходный код.
Ответ №1:
ХОРОШО! Я не видел.
Ваша основная проблема связана с пространством имен: движок XSLT не знает, что такое gesmes, поэтому вам нужно сообщить об этом. Поэтому вам нужно добавить его в свой тег xsl: stylesheet.
- xmlns:gesmes=»http://www.gesmes.org/xml/2002-08-01 «
Вам нужно добавить и назвать пространство имен для пространства имен по умолчанию вашего xml :
- xmlns: xx=»http://www.ecb.int/vocabulary/2002-08-01/eurofxref » итак, ваша таблица стилей будет начинаться с :
<xsl:версия таблицы стилей=»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:для каждого select=»/gesmes:Envelope/xx:Cube/xx:Cube/xx:Cube»>
И это должно сработать … но я предлагаю вам использовать шаблон вместо xsl: для каждого
Вот решение, которое я предлагаю: ХОРОШО! Я не видел.
Ваша основная проблема связана с пространством имен: движок XSLT не знает, что такое gesmes, поэтому вам нужно сообщить об этом. Поэтому вам нужно добавить его в свой тег xsl: stylesheet.
- xmlns:gesmes=»http://www.gesmes.org/xml/2002-08-01 «
Вам нужно добавить и назвать пространство имен для пространства имен по умолчанию вашего xml :
- xmlns: xx=»http://www.ecb.int/vocabulary/2002-08-01/eurofxref » итак, ваша таблица стилей будет начинаться с :
<xsl:версия таблицы стилей=»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:для каждого select=»/gesmes:Envelope/xx:Cube/xx:Cube/xx:Cube»>
И это должно сработать … но я предлагаю вам использовать шаблон вместо xsl: для каждого
Вот решение, которое я предлагаю :
<?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>
Ответ №2:
Кажется, вы хотите что-то вроде этого (я только что отредактировал ваш код — мое собственное решение было бы другим):
<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>
При применении к предоставленному XML-документу:
<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>
получен желаемый, правильный результат:
<?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>
Мои собственные решения были бы больше похожи на это:
<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>
Комментарии:
1. И затем я просто запускаю файл .xsl? Поскольку это показывает мне неправильно, я вижу исходный код, и это неправильно.
2. @user1006959: Вам нужно скопировать код, вставить его в текстовый редактор и сохранить в файле. Затем примените преобразование в этом файле к файлу, содержащему исходный XML (используя любой метод, который вы предпочитаете, например, из командной строки). Я никогда не публикую непроверенные решения. Как и в этом случае, я всегда запускаю решение и проверяю, дает ли оно ожидаемый результат. Затем я просто копирую код и вставляю его в свой ответ SO. Если у вас возникли проблемы с запуском преобразования, пожалуйста, просто задайте другой вопрос.
3. Хорошо, я создал два новых файла. Я скопировал исходный код в эти файлы. Но когда я запускаю его в Opera, Chrome или Safari, он показывает мне только этот «Курс валюты». У вас есть какие-либо идеи?
4. @user1006959: это худший метод выполнения преобразования, о котором я знаю. В любом случае, убедитесь, что имя файла в таблице стилей xml PI совпадает с именем файла, в котором вы сохранили решение. Кроме того, попробуйте изменить метод вывода на «html», то есть:
<xsl:output method="html: .../>
5. Спасибо, но мне это не помогает.
Ответ №3:
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>
Вывод:
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