нужна помощь по XSLT - сделать преобразование XML элемента в самого себя

12
euhenio
На сайте с 21.09.2001
Offline
357
1028

Для дальнейшего улучшения кнопки под яндекс-бар нужно.

Очень хочется часто менять кнопку. Индивидуально даже. Сама кнопка делается как дерево XML. Я в качестве исходных данных со своего сервера получаю тоже XML, но не могу взять один из его узлов и чистом виде вывести в кнопку - не поддерживает. Только через применение xslt-преобразования.

Сейчас мне приходится заранее знать, какого рода теги можно использовать.

Нужно примерно следующее - чтобы я применял xslt-преобразование к некоему узлу входящего XML и получал на выходе ровно то же самое.

Могут быть заранее неизвестные теги

Может быть заранее неизвестная вложенность

Могут быть дублирования тегов

Могут быть параметры у самих тегов, их тоже желательно поддерживать.

Возможно ли это? м.б. частично возможно?

Самая простая формулировка задачи - "преобразовать в самого себя".

PS

Или не помощь, а за бабло. Сколько стоит?

с ув., Евгений Трофименко seo блог Trofimenko.ru ( http://trofimenko.ru/ ) но ыыы мало обновляется... Tools.Promosite.ru - анализатор апдейтов Яндекса (пожертвуйте лимиты на Яндекс.XML! ( https://searchengines.guru/ru/forum/801888/page7#comment_11942489 )) Konvr.ru - увеличение конверсии сайта на 81% за 4 недели ( http://konvr.ru/ )
ДП
На сайте с 23.11.2009
Offline
203
#1

http://www.raleigh.ru/XML/XSLTutorial/24.htm

 <xsl:copy-of select="."/> 
- не подойдет?
euhenio
На сайте с 21.09.2001
Offline
357
#2

Дикий пионер, пробовал так

<xsl:copy-of select="buttons" />

buttons - имя узла.

Не пашет.

из мануалов понял, что то ли оно копирует только один уровень...

а может и такое быть, что яндекс не поддерживает

euhenio
На сайте с 21.09.2001
Offline
357
#3

XML такой

<data>
<buttons>
<button xmlns="http://bar.yandex.ru/dev/gui">
<text>
чваваыаывав
</text>
</button>
</buttons>
</data>

xslt такой

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="data">
<result>
<xsl:copy-of select="buttons" />
</result>
</xsl:template>
</xsl:stylesheet>

- и это не пашет

Ошибок там нет? Я имею в виду - в смысле пути к элементу buttons

ДП
На сайте с 23.11.2009
Offline
203
#4

пока я отвечал, вы запостили ваши xml/xslt, сейчас попробую разобраться.

euhenio
На сайте с 21.09.2001
Offline
357
#5

Но если точно xsl:copy-of должен копировать всю структуру, а не один уровень, может, просто яндекс не поддерживает...

Хотя на то они и стандарты же, должно все работать.

ДП
На сайте с 23.11.2009
Offline
203
#6

Я с преобразованиями xml/xslt только в php работал - там ваш xslt работает успешно.


<?xml version="1.0"?>
<result><buttons>
<button xmlns="http://bar.yandex.ru/dev/gui">
<text>
чваваыаывав
</text>
</button>
</buttons></result>

Вот что выдает.

euhenio
На сайте с 21.09.2001
Offline
357
#7

Значит, яндекс-бар не поддерживает....

А существуют ли какие-нибудь хаки без :copy-of ?

Что-нибудь типа дублирования элемента на основе других операторов xslt?

ДП
На сайте с 23.11.2009
Offline
203
#8

еще вариант - это свой вариант функции copy-of написать через:


<xsl:apply-templates select="@*"/> - выборка всех атрибутов.
<xsl:value-of select="name()"/> - название текущего аттрибута/тега.
<xsl:value-of select="."/> - значение текущего атрибута/тега.

Т.е перебрать все атрибуты тега и все вложенные теги и т.п.

Но как-то это не по феншую будет, как мне кажется.

euhenio
На сайте с 21.09.2001
Offline
357
#9

Дикий пионер, а как это конкретно сделать? Какой код?

ну если они поотключали стандартные возможности, тут не до феншуя )

ДП
На сайте с 23.11.2009
Offline
203
#10

На вашем примере вот такой получился:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="copier">
<!-- копирует переданный элемент -->
<xsl:param name="elem" />
<xsl:element name="{name()}">
<!-- копирует параметры -->
<xsl:for-each select="./@*">
<xsl:attribute name="{name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:for-each>
<!-- параметр xmlns через предыдущее выражение не получается, поэтому его только для тега button прописываем руками -->
<xsl:if test="name()='button'">
<xsl:attribute name="xmlns">
<xsl:value-of select="namespace-uri()" />
</xsl:attribute>
</xsl:if>
<!-- дочерние элементы обрабатываем аналогично -->
<xsl:for-each select="*">
<xsl:call-template name="copier">
<xsl:with-param name="elem" select="." />
</xsl:call-template>
<!-- Текст внутри элементов выводим только для узлов, у которых нет потомков -->
<xsl:if test="string-length(text())!=0 and count(*)=0">
<xsl:value-of select="." />
</xsl:if>
</xsl:for-each>
</xsl:element>

</xsl:template>

<xsl:template match="data">
<result>
<xsl:for-each select="buttons">
<xsl:call-template name="copier">
<xsl:with-param name="elem" select="." />
</xsl:call-template>
</xsl:for-each>
</result>
</xsl:template>
</xsl:stylesheet>

Тут рекурсивно обходим все эелменты внутри заданного, копируем атрибуты, для тега button копируем xmlns (так как он за атрибут похоже не считается), для элементов, у которых нет потомков и есть текст - выводим его.

Правда я это на php тестировал, не знаю уж получится ли с яндекс.баром.

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий