Есть ли элемент имени XSLT?

102

В XSLT есть

<xsl:value-of select="expression"/>

чтобы получить значение элемента, но есть ли что-то для выбора имени тега элемента?

В такой ситуации:

<person>
  <!-- required stuff -->
  <name>Robert</name>
  <!-- optional stuff, free form for future extension. 
       Using XMLSchema's xsd:any -->
  <profession>programmer</profession>
  <hobby>photography</hobby>
</person>

<xsl:for-each select="person">
   <xsl:tag-of select="."/> : <xsl:value-of select="."/>
</xsl:for-each>

Чтобы получить такой вывод:

name : Robert
profession : programmer
hobby : photography

Конечно, приведенный выше XSLT не компилируется, потому что

 <xsl:tag-of select="expression"/>

не существует. Но как это можно было сделать?

Роберт Гулд
источник
Наиболее актуальный тег для этого вопроса - XPath. Обе функции являются стандартными функциями XPath и могут использоваться в выражении XPath в контексте любого языка хостинга (C #, XSLT, XQuery, ...) Пожалуйста,
измените
Этот текст: «В XSLT есть <xsd: value-of select =" expression "/>" - содержит ошибку. Обычно для инструкций XSLT используется префикс «xsl». Обычно при использовании схемы XML мы используем префикс «xsd» или «xs». Пожалуйста исправьте.
Dimitre Novatchev

Ответы:

158

Это даст вам текущее имя элемента (имя тега)

<xsl:value-of select ="name(.)"/>

OP-Edit: Это тоже поможет:

<xsl:value-of select ="local-name()"/>
SO Пользователь
источник
12
local-name - это то, что вы хотите 9 раз из 10
annakata,
20
local-name - это без пространства имен, поэтому обычно это лучше.
Джон В.
102

Никто не указал на тонкую разницу в семантике функций name()и local-name().

  • name(someNode) возвращает полное имя узла, включая префикс и двоеточие, если узел является элементом или атрибутом.
  • local-name(someNode) возвращает только локальное имя узла и не включает префикс и двоеточие в случае, если узел является элементом или атрибутом.

Следовательно, в ситуациях, когда имя может принадлежать двум разным пространствам имен, необходимо использовать name()функцию, чтобы эти имена по-прежнему различались.

И, кстати, можно указать обе функции без аргументов :

name() это сокращение от name(.)

local-name() это сокращение от local-name(.)

Наконец , помните, что не только элементы и атрибуты имеют имена, эти две функции также могут использоваться в PI, и в них они идентичны).

Димитр Новачев
источник
15
<xsl:for-each select="person">
  <xsl:for-each select="*">
    <xsl:value-of select="local-name()"/> : <xsl:value-of select="."/>
  </xsl:for-each>  
</xsl:for-each>
Рэй Лу
источник
Рекомендуется всегда использовать normalize-space () при получении значения узла <xsl: value-of select = "normalize-space (.)" />. Это приведет к сокращению лишних пробелов
SO User
Такая нормализация / дезинфекция потребовалась бы только в том случае, если бы она не выполнялась на этапе сбора входных данных. Это избавляет от необходимости делать это во время доступа, что обычно происходит гораздо чаще. Это можно сделать перед добавлением в RDB, а XML-документ - это просто еще одна база данных.
Патанджали
9

Для желающих нет:

<xsl:tag-of select="."/>

Однако вы можете воссоздать тег / элемент, выполнив следующие действия:

<xsl:element name="{local-name()}">
  <xsl:value-of select="substring(.,1,3)"/>
</xsl:element>

Это полезно в шаблоне xslt, который, например, обрабатывает значения данных форматирования для множества различных элементов. Когда вы не знаете имя элемента, над которым работаете, но вы все еще можете вывести тот же элемент и при необходимости изменить значение.

Тим
источник
6
<xsl:value-of select="name(.)" /> : <xsl:value-of select="."/>
Роуленд Шоу
источник
Так почему за это проголосовали? Конечно, можно было бы упомянуть local-name (), если бы вам тоже не нужно было пространство имен, но для более широкого сообщества было бы полезно объяснить, почему это не сработает.
Роуленд Шоу,
Возможно, он не смог преобразовать данный XML. имя (.) в этом случае будет "person". это должно быть «имя», «профессия» и «хобби».
Рэй Лу,
@CodeMelt Почему тогда вы не проголосовали против принятого ответа? Он хорош, но даже менее конкретен, чем этот. Я поддержал ответ Роуленда Шоу, поскольку он дает ответ на вопрос. Пожалуйста, голосуйте против, только если ответ содержит неверную, неверную или вводящую в заблуждение информацию
Димитр Новачев
4
Исправлена ​​эта незначительная деталь - лично я думаю, что люди должны объяснять, почему что-то получает отрицательное голосование, поскольку это помогает объяснить коллективное знание ...
Роуланд Шоу
Наша репутация может привлекать внимание, но поскольку она не является гарантией того, что то, что мы опубликовали, стоит того, действительно имеет значение качество нашего вклада. Отсутствие доводов в пользу плохого качества вкладов.
Патанджали