Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / xpath и текстовая нода / 7 сообщений из 7, страница 1 из 1
11.08.2007, 17:57
    #34721825
joshua
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
xpath и текстовая нода
Если предположить на секундочку, что у нас есть такой xml

<root>
<elem>что-то</elem>
где-то
</root>

какой xpath у "где-то"?

Пишу /root получаю
что-то
где-то

Пишу /root[text()], получаю то же самое. Даже /root/self::*[text()] работает не так, как я ожидаю. Где я дурак?
...
Рейтинг: 0 / 0
13.08.2007, 07:13
    #34722662
SuSa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
xpath и текстовая нода
joshuaЕсли предположить на секундочку, что у нас есть такой xml

<root>
<elem>что-то</elem>
где-то
</root>

какой xpath у "где-то"?

Пишу /root получаю
что-то
где-то

Пишу /root[text()], получаю то же самое. Даже /root/self::*[text()] работает не так, как я ожидаю. Где я дурак?
У тебя текст между нодами, что само по себе ошибка. xml конечно пофиг, но синтаксически не верно. если надо выражение используй это:
/root[text()] - но с оговоркой что между текстом и корневым узлом нодов нет, или что родительским узлом для текста является корневой элемент.
...
Рейтинг: 0 / 0
15.08.2007, 10:09
    #34728397
SuSa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
xpath и текстовая нода
Чтоб получить текст "где-то" из такой структуры:
Код: plaintext
1.
2.
3.
<root>
<elem>что-то</elem>
где-то
</root>
достаточно написать так:
Код: plaintext
<xsl:value-of select="root/text()"/>
Правда вылезит некрасиво :)
...
Рейтинг: 0 / 0
15.08.2007, 22:03
    #34730862
joshua
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
xpath и текстовая нода
SuSa, спасибо. На самом деле, если поставить текстовую ноду первой все получается. А вот второй совет работает только после перестановок. И мне непонятно, почему все происходит именно так.

После ужасных раздумьев получилось только /root/text()[position()=last()] что, безусловно, ужОс :(
...
Рейтинг: 0 / 0
16.08.2007, 09:22
    #34731238
SuSanin_nik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
xpath и текстовая нода
joshuaSuSa, спасибо. На самом деле, если поставить текстовую ноду первой все получается. А вот второй совет работает только после перестановок. И мне непонятно, почему все происходит именно так.

После ужасных раздумьев получилось только /root/text()[position()=last()] что, безусловно, ужОс :(
Если напишешь вот так:
Код: plaintext
текст='<xsl:value-of select="root/text()"/>'
То увидешь что результат равен следующему:
Код: plaintext
1.
2.
3.
text='
    
    где-то
'
Если глянешь на исходы то заметишь, что на месте первой пустой строки в результате, в исходах стоит твой тег <elem>
Если текст с тегом поменяешь, то строчки в результате также поменяются местами.
ф-ция normalize-space() не поможет, но даст подсказку почему она не может.
Выводы можешь сделать сам :)
...
Рейтинг: 0 / 0
16.08.2007, 09:40
    #34731288
TiG
TiG
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
xpath и текстовая нода
joshuaSuSa, спасибо. На самом деле, если поставить текстовую ноду первой все получается. А вот второй совет работает только после перестановок. И мне непонятно, почему все происходит именно так.
Если глянуть в доку :
The xsl:value-of element is instantiated to create a text node in the result tree. The required select attribute is an expression; this expression is evaluated and the resulting object is converted to a string as if by a call to the string function.
и далее
The string function converts an object to a string as follows:
A node-set is converted to a string by returning the string-value of the node in the node-set that is first in document order .
А у вас естественно 2 текстовых узла: 1ый - это перевод строки, потом идет elem, потом 2ой текстовый узел - перевод строки + "где-то" + перевод строки. Хорошо видно если сделать так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="windows-1251"/>

<xsl:template match="/">
<xsl:for-each select="root/text()">-<xsl:value-of select="position()"/><xsl:value-of select="."/>-</xsl:for-each>
</xsl:template>

</xsl:stylesheet>
Потому то срабатывает:
joshuaПосле ужасных раздумьев получилось только /root/text()[position()=last()] что, безусловно, ужОс :(
Поэтому, во-первых, надо собирать все текстовые узлы (в этом поможет copy-of который подряд идущие на выходе текстовые узлы собирает в один), а во-вторых, отсеивать лишние "пустые":
Код: plaintext
1.
<xsl:copy-of select="root/text()[normalize-space(.) != '']"/>
При желании еще и каждый из них почистить от лишних переводов строк - тогда for-each по всем текстовым узлам + вывод нормализованного значения узла.
...
Рейтинг: 0 / 0
16.08.2007, 10:03
    #34731360
SuSa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
xpath и текстовая нода
Не сильно понял нафига нужен был цикл, но! если текст между тегов встречается только один раз, то можно обойтись вот такой конструкцией:
Код: plaintext
<xsl:copy-of select="normalize-space(root/text()[normalize-space(.) != ''])"/>
без использования всякого цикла.
Если больше, то лучше циклом и тем способом что предложил TiG.
...
Рейтинг: 0 / 0
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / xpath и текстовая нода / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]