Czy istnieje element nazwy XSLT?

102

W XSLT jest

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

aby uzyskać wartość elementu, ale czy jest coś do wybrania nazwy znacznika elementu?

W takiej sytuacji:

<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>

Aby uzyskać takie wyniki:

name : Robert
profession : programmer
hobby : photography

Oczywiście powyższy XSLT nie skompiluje się, ponieważ

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

nie istnieje. Ale jak można to zrobić?

Robert Gould
źródło
Najbardziej odpowiednim tagiem dla tego pytania jest XPath. Obie funkcje są standardowymi funkcjami XPath i mogą być używane w wyrażeniu XPath w kontekście dowolnego języka hostingu (C #, XSLT, XQuery, ...) Proszę o ponowne oznaczenie
Dimitre Novatchev
Ten tekst: „W XSLT jest <xsd: value-of select =" expression "/>" - zawiera błąd. Zwykle używany przedrostek dla instrukcji XSLT to „xsl”. Zwykle używając schematu XML używamy przedrostka „xsd” lub „xs”. Proszę popraw.
Dimitre Novatchev

Odpowiedzi:

158

To da ci aktualną nazwę elementu (nazwę tagu)

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

OP-Edit: To również załatwi sprawę:

<xsl:value-of select ="local-name()"/>
Użytkownik SO
źródło
12
nazwa-lokalna jest tym, czego chcesz 9 razy na 10
annakata,
20
nazwa-lokalna to bez przestrzeni nazw, dlatego zwykle jest lepsza.
Jon W
102

Nikt nie wskazał na subtelną różnicę w semantyce funkcji name()i local-name().

  • name(someNode) zwraca pełną nazwę węzła, która zawiera przedrostek i dwukropek w przypadku, gdy węzeł jest elementem lub atrybutem.
  • local-name(someNode) zwraca tylko lokalną nazwę węzła i nie zawiera przedrostka i dwukropka w przypadku, gdy węzeł jest elementem lub atrybutem.

Dlatego w sytuacjach, gdy nazwa może należeć do dwóch różnych przestrzeni nazw, należy użyć name()funkcji, aby te nazwy były nadal rozróżniane.

I przy okazji, można określić obie funkcje bez żadnego argumentu :

name() to skrót od name(.)

local-name() to skrót od local-name(.)

Na koniec pamiętaj, że nie tylko elementy i atrybuty mają nazwy, te dwie funkcje mogą być również używane na PI i na nich są identyczne).

Dimitre Novatchev
źródło
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>
Ray Lu
źródło
Dobrą praktyką jest zawsze używanie normalize-space () podczas pobierania wartości-węzła <xsl: value-of select = "normalize-space (.)" /> Spowoduje to obcięcie dodatkowych spacji
użytkownik SO
Taka normalizacja / odkażanie byłaby potrzebna tylko wtedy, gdyby nie została podjęta na etapie gromadzenia danych wejściowych. Dzięki temu oszczędza się konieczności robienia tego w czasie dostępu, co jest zwykle znacznie częstsze. Można to zrobić przed dodaniem do RDB, a dokument xml to tylko kolejna baza danych.
Patanjali,
9

Dla zainteresowanych nie ma:

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

Możesz jednak odtworzyć tag / element, przechodząc:

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

Jest to przydatne w szablonie xslt, który na przykład obsługuje formatowanie wartości danych dla wielu różnych elementów. Jeśli nie znasz nazwy elementu, nad którym pracujesz, i nadal możesz wyprowadzić ten sam element i zmodyfikować wartość, jeśli zajdzie taka potrzeba.

Tim
źródło
6
<xsl:value-of select="name(.)" /> : <xsl:value-of select="."/>
Rowland Shaw
źródło
Więc dlaczego to padło w głosowaniu? Granted mógłbyś wspomnieć local-name (), gdybyś nie chciał również przestrzeni nazw, ale byłoby przydatne dla szerszej społeczności, aby wyjaśnić, dlaczego to nie zadziała.
Rowland Shaw
Być może nie mógł przekształcić podanego XML. w tym przypadku nazwa (.) będzie brzmiała „osoba”. powinno to być „imię”, „zawód” i „hobby”.
Ray Lu,
@CodeMelt Dlaczego więc nie odrzuciłeś zaakceptowanej odpowiedzi? Jest dobry, ale jest jeszcze mniej szczegółowy niż ten. Głosowałem za odpowiedzią Rowland Shaw, ponieważ zawiera ona odpowiedź na pytanie. Proszę, głosuj w dół tylko wtedy, gdy odpowiedź zawiera błędne, niepoprawne lub wprowadzające w błąd informacje
Dimitre Novatchev
4
Naprawiono ten drobny szczegół - osobiście uważam, że ludzie powinni wyjaśnić, dlaczego coś jest odrzucane, ponieważ pomaga to wyjaśnić zbiorową wiedzę ...
Rowland Shaw,
Nasza reputacja może przyciągać uwagę, ale ponieważ nie dają one gwarancji, że to, co opublikowaliśmy, jest warte zachodu, naprawdę liczy się jakość naszego wkładu. Brak uzasadnienia przemawia za niską jakością wkładów.
Patanjali,