Выберите текст из узла и пропустите дочерние узлы - PullRequest
6 голосов
/ 03 марта 2011

Мне нужно выделить текст в узле, но не в дочерних узлах. XML выглядит так

<a>
  apples  
  <b><c/></b>
  pears
</a>

Если я выберу a/text(), все, что я получу, это " яблок ". Как бы я получил " яблочных груш ", пропуская <b><c/></b>

Ответы [ 3 ]

4 голосов
/ 03 марта 2011

Хорошо, путь a/text() выбирает все текстовые дочерние узлы элемента a, поэтому путь, по моему мнению, является правильным. Только если вы используете этот путь, например, с XSLT 1.0 и <xsl:value-of select="a/text()"/> выводит строковое значение первого выбранного узла. В XPath 2.0 и XQuery 1.0: string-join(a/text()/normalize-space(), ' ') возвращает строку apples pears, так что, возможно, это поможет решить вашу проблему. Если нет, то попробуйте объяснить, в каком контексте вы используете XPath или XQuery, чтобы a/text() возвращало только значение (строка?) Первого выбранного узла.

0 голосов
/ 05 марта 2011

Если я выберу / text (), я получу только «яблоки».Как бы я получил "яблочные груши"

Просто используйте :

normalize-space(/)

Объяснение :

TheСтроковое значение корневого узла (/) документа является объединением всех его потомков текстовых узлов.Поскольку существуют текстовые узлы только для пробелов, нам нужно устранить эти нежелательные текстовые узлы.

Вот небольшая демонстрация , как работает это решение и что оно производит:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="/">
  '<xsl:value-of select="normalize-space()"/>'
 </xsl:template>
</xsl:stylesheet>

, когда это преобразование применяется к предоставленному XML-документу:

<a>
 apples
    <b><c/></b>
 pears
</a>

желаемый, правильный результат:

  'apples pears'
0 голосов
/ 03 марта 2011

Для извлечения всех потомков я советую использовать // нотацию. Это вернет всех текстовых потомков ниже элемента. Ниже приведен фрагмент кода xquery, который получает все текстовые узлы-потомки и форматирует его, как указал Мартин.

xquery version "1.0";
let $a := 
<a>
  apples  
  <b><c/></b>
  pears
</a>
return normalize-space(string-join($a//text(), " "))

Или, если у вас есть свои собственные требования к форматированию, вы можете начать с просмотра каждого текстового элемента в следующем xquery.

xquery version "1.0";
let $a := 
<a>
  apples  
  <b><c/></b>
  pears
</a>
for $txt in $a//text()
return $txt
...