Модераторы: diadiavova
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как найти все узлы между двумя узлами с помощью XS 
V
    Опции темы
Hinikato
Дата 20.5.2011, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 18.2.2007

Репутация: нет
Всего: нет



Здравствуйте!

Прошу помощи в решении следующей задачи: у меня есть XML документ, упрощенно для лучшего понимания задачи такой:
Код

<?xml version="1.0" encoding="utf-8"?>
<pricelist>
  <category>Категория 1</category>
  <vendor>Производитель 1.1.</vendor>
  <product>Продукт 1.1.1</product>
  <product>Продукт 1.1.2</product>
  <product>Продукт 1.1.3</product>
  <category>Категория 2</category>
  <product>Продукт 2.1</product>
  <vendor>Производитель 2.1</vendor>
  <product>Продукт 2.1.1</product>
  <product>Продукт 2.1.2</product>
</pricelist>

Нужно его преобразовать в древовидный вид, а именно такой:
Код

<?xml version="1.0" encoding="utf-8"?>
<pricelist>
  <category name="Категория 1">
    <vendor name="Производитель 1.1.">
      <product>Продукт 1.1.1</product>
      <product>Продукт 1.1.2</product>
      <product>Продукт 1.1.3</product>
    </vendor>
  </category>
  <category name="Категория 2">
    <vendor name="Unknown">
      <product>Продукт 2.x</product>
    </vendor>
    <vendor name="Производитель 2.1">
      <product>Продукт 2.1.1</product>
      <product>Продукт 2.1.2</product>
    </vendor>
  </category>
</pricelist>

Некоторые пояснения:
- продукты для которых не указан производитель попадают в специальный производитель с именем Unknown, такой Unknown производитель может быть только один в каждой категории.
- цифры у продуктов и производителей я добавил только для примера.
- вообще в прайсе все имена категорий уникальны.
- имена продуктов и производителей уникальны в пределах категории, но могут повторяться в пределах прайса.

Я только начал изучать XLST, написал пока такой .xsl файл (могут быть ошибки, т.к. я его переделал для этого упрощенного примера:
Код

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

    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="table">
      <pricelist>
      <xsl:apply-templates select="//category"/>
      </pricelist>
    </xsl:template>

    <xsl:template match="category">
      <xsl:variable name="category_name">
        <xsl:value-of select="child::text()"/>
      </xsl:variable>
      <category name="{$category_name}">
        <xsl:variable name="next_category"
                     select="(self::node()/following-sibling::category)[1]" />
        <xsl:variable name="current_category" select="self::node()"/>
<!--
Тут непонятно что писать...

Я нашел фрагмент со следующей страницы: http://www.biglist.com/lists/xsl-list/archives/200201/msg00659.html
 <xsl:copy-of select="following-sibling::*
                        [generate-id(following-sibling::comma[1]) =
                         generate-id($next-comma)]" />
Но как его использовать здесь непонятно...
-->  

      </category>
    </xsl:template>
</xsl:stylesheet>

Пояснения и вопрос еще я добавил в комментариях XML.

Прошу помощи именно по XML части. Как можно получить на выходе документ в нужном виде из исходного?
PM MAIL   Вверх
diadiavova
Дата 20.5.2011, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Доктор Зло(диагност, настоящий, с лицензией и полномочиями)
****


Профиль
Группа: Модератор
Сообщений: 5821
Регистрация: 14.8.2008
Где: В Коньфпольте

Репутация: 22
Всего: 142



Честно говоря не знаю, как это будет работать на реальном примере, а не на упрощенном(надо проверять), но так вроде работает. Думаю, в случае чего, разберешься в логике и подправишь.
Код

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />

  <xsl:template match="/">
    <pricelist>
      <xsl:apply-templates select="//category"/>
    </pricelist>
  </xsl:template>

    <xsl:template match="//category">
        <category name="{.}">
      <xsl:variable name="curcat" select="."/>
      <xsl:variable name="nodes" 
                    select="
                        following-sibling::product[preceding-sibling::*
                            [(name() = 'vendor') or (name() = 'category')][1] = $curcat]"/>
            <xsl:if test="$nodes">
                <vendor name="Unknown">
                    <xsl:for-each select="$nodes">
                        <xsl:copy-of select="."/>
                    </xsl:for-each>
                </vendor>
            </xsl:if>
      <xsl:for-each select="following-sibling::vendor[preceding-sibling::category[1] = $curcat]">
        <xsl:variable name="curven" select="."/>
        <vendor name="{$curven}">
          <xsl:for-each select="following-sibling::product[(preceding-sibling::vendor[1] = $curven) and 
                                    (preceding-sibling::category[1] = $curcat)]">
            <xsl:copy-of select="."/>
          </xsl:for-each>
        </vendor>
      </xsl:for-each>
        </category>
    </xsl:template>
</xsl:stylesheet>




--------------------
Хочешь получить мудрый совет - читай подписи участников форумов.
Злой доктор Щасзаболит smile
PM   Вверх
Hinikato
Дата 25.5.2011, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 18.2.2007

Репутация: нет
Всего: нет



diadiavova, спасибо тебе огромное за помощь. Так получилось, что к моменту как ты написал это сообщение мне уже помогли решить задачу

НО, твое решение, я думаю пригодится очень многим, да может быть и мне в будущем, спасибо за помощь!

Добавлено через 40 секунд
Вопрос решен.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "XML/XSLT"
diadiavova

Прежде чем опубликовать вопрос, попробуйте воспользоваться поиском - возможно тема уже поднималась.

Также рекомендуем Вам зайти в раздел FAQ ,раздел дополняется и, возможно, там вы увидите готовое решение.

Для ответов на часто задаваемые вопросы существует FAQ раздела. Новости можно публиковать в разделе новостей. Для статей так же есть специальный раздел

Желаем удачи в Вашем деле!


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, diadiavova.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | XML, XSL | Следующая тема »


 




[ Время генерации скрипта: 0.0849 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.