Hueker
Заглянувший
Joined: 08 Jan 2007
Posts: 14
Карма: -22 поощрить/наказать
|
Posted: Thu May 19, 2011 11:32 pm (написано за 15 минут 12 секунд)
Post subject: Поиск узлов между двумя узлами с помощью XSLT. Как?
|
|
Здравствуйте! Прошу помощи в решении следующей задачи: у меня есть XML документ, упрощенно для лучшего понимания задачи такой: Code (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> | Нужно его преобразовать в древовидный вид, а именно такой: Code (xml): | скопировать код в буфер обмена | <?xml version="1.0" encoding="utf-8"?> <pricelist> <category name=" 1"> <vendor name=" 1.1."> <product></product> <product></product> <product></product> </vendor> </category> <category name=" 2"> <vendor name="Unknown"> <product></product> </vendor> <vendor name=" 2.1"> <product></product> <product></product> </vendor> </category> </pricelist> | Некоторые пояснения: - продукты для которых не указан производитель попадают в специальный производитель с именем Unknown, такой Unknown производитель может быть только один в каждой категории. - цифры у продуктов и производителей я добавил только для примера. - вообще в прайсе все имена категорий уникальны. - имена продуктов и производителей уникальны в пределах категории, но могут повторяться в пределах прайса. Я только начал изучать XLST, написал пока такой .xsl файл (могут быть ошибки, т.к. я его переделал для этого упрощенного примера, но главное суть): Code (xml): | скопировать код в буфер обмена | <?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 будет обработан PHP скриптом. Прошу помощи именно по XML части. Как можно получить на выходе документ в нужном виде из исходного?
|
|
Hueker
Заглянувший
Joined: 08 Jan 2007
Posts: 14
Карма: -22 поощрить/наказать
|
Posted: Sat May 21, 2011 8:25 am (спустя 1 день 8 часов 52 минуты; написано за 36 секунд)
Post subject:
|
|
Решение было получено, благодаря человеку с ником ss, за что ему огромное спасибо! Привожу решение: Code (xml): | скопировать код в буфер обмена | <?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:template match="/"> <pricelist> <xsl:apply-templates select="pricelist/category"/> </pricelist> </xsl:template>
<xsl:template match="category"> <xsl:apply-templates select="pricelist/category"/> <category name="{./text()}"> <xsl:apply-templates select="current()[following-sibling::*[1][self::product]]" mode="unknown"/>
<xsl:apply-templates select="." mode="vendors"/> </category> </xsl:template>
<xsl:template match="*"/>
<!--//////////////////////////////////////////////////////////////////////////////-->
<xsl:template match="category" mode="unknown"> <vendor name="Unknown"> <xsl:apply-templates select="following-sibling::*[1][self::product]" mode="products"/> </vendor> </xsl:template>
<xsl:template match="*" mode="unknown"/>
<!--//////////////////////////////////////////////////////////////////////////////-->
<xsl:template match="product" mode="products"> <xsl:copy-of select="."/>
<xsl:apply-templates select="following-sibling::*[1][self::product]" mode="products"/> </xsl:template>
<xsl:template match="*" mode="products"/>
<!--//////////////////////////////////////////////////////////////////////////////-->
<xsl:template match="vendor" mode="vendor"> <vendor name="{./text()}"> <xsl:apply-templates select="following-sibling::*[1][self::product]" mode="products"/> </vendor> </xsl:template>
<xsl:template match="*" mode="vendor"/>
<!--//////////////////////////////////////////////////////////////////////////////-->
<xsl:template match="category | vendor" mode="vendors"> <xsl:apply-templates select="." mode="vendor"/>
<xsl:variable name="first_vendor" select="following-sibling::vendor[1]"/> <xsl:variable name="next_category" select="following-sibling::category[1]"/>
<xsl:apply-templates select="$first_vendor[not(. = $next_category/following-sibling::*)]" mode="vendors"/> </xsl:template>
<xsl:template match="*" mode="vendors"/>
</xsl:stylesheet> | Вопрос решен, тему можно закрыть.
|
|
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sat May 21, 2011 2:05 pm (спустя 5 часов 39 минут; написано за 4 минуты 54 секунды)
Post subject:
|
|
Задача интересная. Если это полноценное готовое решение, то его стоит оставить в топе. Когда-то мне понадобилось конвертировать в xml/html-формат некий текстовый файл, содержащий иерархическую реестр-подобную структуру. В свое время решил нескольким десятков строк чистого кода без использования xslt. Добавил 2 балла.
|
|
bæv
Модератор «Дзена»

Joined: 27 Aug 2003
Posts: 7275
Карма: 9986 поощрить/наказать
|
Posted: Mon Mar 26, 2012 2:53 pm (спустя 10 месяцев 5 дней 48 минут)
Post subject:
|
|
 М |
| Ветка выделена в отдельную тему «спам», расположенную в форуме Мусоропровод (26 Марта 2012, 15:53). |
|
|