XPATH
От: SeLo  
Дата: 10.02.17 10:35
Оценка:
есть хмл


<x>
<y>Текст не нужун</y>
<z>текст1</z>
текст2
<z>текст3</z>
</x>

нужно получить текствое значение элемента x, без поделемента y.

текст1
текст2
текст3

пробую как то так, не получается
string(x/self::node()[not(y)])
Отредактировано 10.02.2017 10:35 SeLo . Предыдущая версия .
Re: XPATH
От: · Великобритания  
Дата: 10.02.17 10:58
Оценка:
Здравствуйте, SeLo, Вы писали:

SL>пробую как то так, не получается

SL>string(x/self::node()[not(y)])
Ты можешь выбрать нужные тебе текстовые узлы как: /x/descendant-or-self::*[not(self::y)]/text()
Но создать результат, который конкатинирует эти узлы в одну строку ты не можешь в чистом XPATH. Либо тебе нужен XSLT, либо XPATH2.0 string-join, либо соединить их какой-нибудь внешней функцией.

А в таком случае — содержимое <b> нужно?
<x>
    <y>Текст <b>не</b> нужун</y>
    <z>текст1</z>
    текст2
    <z>текст3</z>
</x>

Если не нужно, пиши так: /x/descendant-or-self::*[not(ancestor-or-self::y)]/text()
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: XPATH
От: SeLo  
Дата: 10.02.17 13:29
Оценка:
·>Ты можешь выбрать нужные тебе текстовые узлы как: /x/descendant-or-self::*[not(self::y)]/text()
·>Если не нужно, пиши так: /x/descendant-or-self::*[not(ancestor-or-self::y)]/text()


<b> не нужен, он случайно здесь вставился.
В общем, что-то никак не выходит. Работаю действительно с XSLT.
сделал темплейт для содинения строк

<xsl:template match="*" mode="my_concat" >
<xsl:for-each select="descendant::*">
<!--<xsl:if test="position() != 1">, </xsl:if>-->
<xsl:value-of select="./text()"/>
</xsl:for-each>
</xsl:template>

<xsl:apply-templates select="x/descendant-or-self::*[not(self::y)]" mode="my_concat" />

и пытаюсь выбрать, как ты мне сказал. все равно все проходят и значения "y" выводятся.
Re[3]: XPATH
От: · Великобритания  
Дата: 10.02.17 13:53
Оценка:
Здравствуйте, SeLo, Вы писали:

SL><xsl:apply-templates select="x/descendant-or-self::*[not(self::y)]" mode="my_concat" />

Тут ты выбрал все узлы кроме "y", включая "x".

SL>и пытаюсь выбрать, как ты мне сказал. все равно все проходят и значения "y" выводятся.

SL><xsl:template match="*" mode="my_concat" >
SL> <xsl:for-each select="descendant::*">
А тут ты выбираешь всех потомков каждого узла выбранного на предыдущем этапе. А "y" является потомком "x".

Если обычный xpath+xslt, то сделай просто. Как слышится так и пишется:
<xsl:apply-templates select="x" mode="filtered"/><!-- фильтруем содержимое x-->
...
<xsl:template match="text()" mode="filtered"><!-- текстовые узлы выводятся как есть -->
  <xsl:value-of select="."/>
</xsl:template>

<xsl:template match="y" mode="filtered"/><!-- для "y" - тупо ничего не делаем -->

<xsl:template match="*" mode="filtered"><!-- в остальные теги заходим рекурсивно -->
  <xsl:apply-templates select="node()"/>
</xsl:template>
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[3]: XPATH
От: · Великобритания  
Дата: 10.02.17 15:02
Оценка: 6 (1)
Здравствуйте, SeLo, Вы писали:

SL><b> не нужен, он случайно здесь вставился.

SL>В общем, что-то никак не выходит. Работаю действительно с XSLT.
Ну а если использовать то выражение и XSLT, то тупо
<xsl:copy-of select="/x/descendant-or-self::*[not(self::y)]/text()"/>
.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[4]: XPATH
От: SeLo  
Дата: 10.02.17 15:57
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, SeLo, Вы писали:


SL>><b> не нужен, он случайно здесь вставился.

SL>>В общем, что-то никак не выходит. Работаю действительно с XSLT.
·>Ну а если использовать то выражение и XSLT, то тупо
<xsl:copy-of select="/x/descendant-or-self::*[not(self::y)]/text()"/>
.


То что нужно!
Сделал так, что бы все в одну линию красиво выводило:


<xsl:variable name="tmp" >
<xsl:copy-of select="/descendant::*[not(self::y)]/text()"/>
</xsl:variable>
<xsl:value-of select="normalize-space($tmp)"/>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.