Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: XSLT-преобразование и xmlns без префикса.  (Прочитано 17489 раз)
0 Пользователей и 1 Гость смотрят эту тему.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« : 04-02-2010 07:16 » 

Года три не брал в руки шашек...
Решил написать XSL для XML-файла формата fb2 (FictionBook). Долго не мог понять, почему не работает.
Вот пример fb2 файла:

Код:
<?xml version="1.0" encoding="UTF-8"?>
<FictionBook xmlns:l="http://www.w3.org/1999/xlink" xmlns="http://www.gribuser.ru/xml/fictionbook/2.0">
  <description>
    ...
  </description>
  <body>
    ...
  </body>
  <binary>
    ...
  </binary>
</FictionBook>

Все теги (за исключением xlink) не имеют префикса пространства имен.
После удаления объявления xmlns без префикса XSL заработал:

Код:
<FictionBook xmlns:l="http://www.w3.org/1999/xlink">

Не могу понять, как работать без удаления этого xmlns...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 04-02-2010 09:20 » 

Был период времени, когда у MS парсер XML работал только при указании префикса, даже если в самом XML префикса у тегов не было. Связано это было как раз с наличием/отсутствием пространств имён. Может до сих пор так работает. Пример неработающего XSL приведи.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 04-02-2010 09:40 » 

Дим, я проверил с FF, с IE7 и с линуксовым xsltproc - все три программы одинаково отказались работать с таким xlmns.

Пример длинный...

Код: (Text)
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>

<xsl:template match="/FictionBook">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <link rel="stylesheet" type="text/css" href="fb2.css"/>
  <title><xsl:value-of select="description/title-info/book-title"/></title>
</head>
<body>
  <div id="title">
    <div class="title"><xsl:value-of select="description/title-info/book-title"/></div>
    <div class="author">
      <xsl:value-of select="description/title-info/author/last-name"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="description/title-info/author/first-name"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="description/title-info/author/middle-name"/>
    </div>
    <div class="isbn">ISBN: <xsl:value-of select="description/publish-info/isbn"/></div>
  </div>
  <div id="contents">
    <xsl:for-each select="body/section">
      <a href="#section{position()}" class="title"><xsl:value-of select="./title/p"/></a>
    </xsl:for-each>
  </div>
  <div id="body">
    <xsl:apply-templates select="body"/>
  </div>
</body>
</html>
</xsl:template>

<xsl:template match="body">
  <xsl:for-each select="section">
    <div id="section{position()}" class="section">
      <xsl:apply-templates/>
    </div>
  </xsl:for-each>
</xsl:template>

<xsl:template match="section/title">
  <div class="title"><xsl:apply-templates/></div>
</xsl:template>

<xsl:template match="title/p">
  <div><xsl:value-of select="."/></div>
</xsl:template>

<xsl:template match="section/subtitle">
  <div class="subtitle"><xsl:apply-templates/></div>
</xsl:template>

<xsl:template match="subtitle/p">
  <div><xsl:value-of select="."/></div>
</xsl:template>

<xsl:template match="p">
  <xsl:choose>
    <xsl:when test="name(child::*) = 'emphasis'">
      <p class="emphasis"><xsl:value-of select="./emphasis"/></p>
    </xsl:when>
    <xsl:otherwise>
      <p><xsl:apply-templates/></p>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

Даже если его сократить до
Код:
<xsl:template match="/FictionBook">aaaa</xsl:template>
, то все равно не работает. А вот без указания имени тега - работает:
Код:
<xsl:template match="/">aaaa</xsl:template>
« Последнее редактирование: 04-02-2010 09:48 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 04-02-2010 11:55 » 

К сожалению, у меня в работающих образцах случая типа:
Код: (XML)
<FictionBook xmlns:l="http://www.w3.org/1999/xlink" xmlns="http://www.gribuser.ru/xml/fictionbook/2.0">
нет. Везде использовано xmlns:...
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 04-02-2010 12:11 » 

Народ, еще кто-нибудь с XSLT работает? Может сталкивались?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #5 : 04-02-2010 14:28 » 

xerces?
Записан

Странно всё это....
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 04-02-2010 15:03 » 

LogRus, ты о чем? Улыбаюсь
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #7 : 04-02-2010 16:23 » 

Ром, xlink используется для связи документов на уровне аттрибутов. в твоём документе атрибуты, описываемые в пространстве имён, задаваемом xmlns="http://www.gribuser.ru/xml/fictionbook/2.0", насколько я понимаю, отстутствуют Улыбаюсь

думается, что либо надо их определить, либо вводить проверку, либо выкинуть xlink.

з.ы. - могу путать, так глубоко в xsl уже давно не приходилось залезать.
Записан

RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 05-02-2010 06:02 » 

Игор, xlink мне не нужен. Он упоминается в документе один раз и используется как ссылка на бинарный объект в теле документа. Дело не в нем, а во всех остальных элементах — они все не находятся через match="TAGNAME" (и через select), даже корневой элемент, если к нему обращаться по имени, а не через "/". Как только убираю xmlns (не xlink!), то все сразу находится.

Думаю, стоит попробовать контекстный поиск, через select="namespace::*".
« Последнее редактирование: 05-02-2010 06:04 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #9 : 05-02-2010 06:20 » 

LogRus, ты о чем? Улыбаюсь

я подумал ты о софтине Улыбаюсь а не о человеках Улыбаюсь
Записан

Странно всё это....
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 05-02-2010 06:58 » 

Да не - меня как раз само XSLT интересует. Улыбаюсь

Посмотрел по ссылке в их xmlns:

1. В примере xsl они используют префикс "fb":
http://www.gribuser.ru/xml/fictionbook/2.0/xsl/export/FB2_2_html.xsl
http://www.gribuser.ru/xml/fictionbook/2.0/xsl/export/FB2_2_html_basics.xsl

2. Слабо понимаю схемы и так не смог понять, где тут объявлено пространство имен:
http://www.gribuser.ru/xml/fictionbook/2.0/xsd/FictionBook2.xsd

Почитал о пространстве имен по умолчанию:
http://www.rol.ru/news/it/helpdesk/xnamsps.htm#defaulting
Яснее не стало.

Если кому интересно - пример FictionBook2:
http://www.gribuser.ru/xml/fictionbook/2.0/example.fb2
« Последнее редактирование: 05-02-2010 07:05 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 07-02-2010 18:32 » 

Немного разобрался. Т.к. пространство имен идентифицируется по строке, указанной в его объявлении, то в xsl нужно объявить его для некого префикса и использовать его:

Код:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fb="http://www.gribuser.ru/xml/fictionbook/2.0">
<xsl:output method="html"/>

<xsl:template match="/fb:FictionBook">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <link rel="stylesheet" type="text/css" href="fb2.css"/>
  <title><xsl:value-of select="fb:description/fb:title-info/fb:book-title"/></title>
</head>
<body>
  <div id="title">
    <div class="title"><xsl:value-of select="fb:description/fb:title-info/fb:book-title"/></div>
    <div class="author">
      <xsl:value-of select="fb:description/fb:title-info/fb:author/fb:last-name"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="fb:description/fb:title-info/fb:author/fb:first-name"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="fb:description/fb:title-info/fb:author/fb:middle-name"/>
    </div>
    <div class="isbn">ISBN: <xsl:value-of select="fb:description/fb:publish-info/fb:isbn"/></div>
  </div>
  <div id="contents">
    <xsl:for-each select="fb:body/fb:section">
      <a href="#section{position()}" class="title"><xsl:value-of select="./fb:title/fb:p"/></a>
    </xsl:for-each>
  </div>
  <div id="body">
    <xsl:apply-templates select="fb:body"/>
  </div>
</body>
</html>
</xsl:template>

<xsl:template match="fb:body">
  <xsl:for-each select="fb:section">
    <div id="section{position()}" class="section">
      <xsl:apply-templates/>
    </div>
  </xsl:for-each>
</xsl:template>

<xsl:template match="fb:section/fb:title">
  <div class="title"><xsl:apply-templates/></div>
</xsl:template>

<xsl:template match="fb:title/fb:p">
  <div><xsl:value-of select="."/></div>
</xsl:template>

<xsl:template match="fb:section/fb:subtitle">
  <div class="subtitle"><xsl:apply-templates/></div>
</xsl:template>

<xsl:template match="fb:subtitle/fb:p">
  <div><xsl:value-of select="."/></div>
</xsl:template>

<xsl:template match="fb:p">
  <xsl:choose>
    <xsl:when test="local-name(child::*) = 'emphasis'">
      <p class="emphasis"><xsl:value-of select="./fb:emphasis"/></p>
    </xsl:when>
    <xsl:otherwise>
      <p><xsl:apply-templates/></p>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

Префиксы в исходном XML и в XSL совпадать не обязаны.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #12 : 08-02-2010 08:22 » 

RXL, в XPath от MS те же прибабахи. Может даже стандарт какой-нибудь есть.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 08-02-2010 10:57 » new

Дим, выше я упоминал такой стандарт:
Почитал о пространстве имен по умолчанию:
http://www.rol.ru/news/it/helpdesk/xnamsps.htm#defaulting
Яснее не стало.

Фигово, что для XML и смежных док чтобы хорошо разбираться надо очень много перелопатить.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines