Gibt es einen XSLT-Elementnamen?

101

In XSLT gibt es die

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

um den Wert eines Elements zu erhalten, aber gibt es etwas, um den Tag-Namen des Elements auszuwählen?

In einer Situation wie dieser:

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

So erhalten Sie eine Ausgabe:

name : Robert
profession : programmer
hobby : photography

Natürlich wird das obige XSLT da nicht kompiliert

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

existiert nicht. Aber wie könnte das gemacht werden?

Robert Gould
quelle
Das relevanteste Tag für diese Frage ist XPath. Beide Funktionen sind XPath-Standardfunktionen und können innerhalb eines XPath-Ausdrucks im Kontext einer beliebigen Hosting-Sprache (C #, XSLT, XQuery, ...) verwendet werden. Bitte erneut markieren
Dimitre Novatchev
Dieser Text: "In XSLT gibt es den <xsd: value-of select =" expression "/>" - enthält einen Fehler. Das normalerweise verwendete Präfix für XSLT-Anweisungen ist "xsl". Normalerweise verwenden wir bei Verwendung des XML-Schemas das Präfix "xsd" oder "xs". Bitte korrigieren.
Dimitre Novatchev

Antworten:

156

Dadurch erhalten Sie den aktuellen Elementnamen (Tag-Name).

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

OP-Edit: Dies reicht auch aus:

<xsl:value-of select ="local-name()"/>
SO Benutzer
quelle
12
lokaler Name ist, was Sie 9 mal von 10 wollen
annakata
20
lokaler Name ist ohne Namespace, deshalb ist es normalerweise besser.
Jon W
102

Niemand hat auf den subtilen Unterschied in der Semantik der Funktionen name()und hingewiesen local-name().

  • name(someNode) Gibt den vollständigen Namen des Knotens zurück, einschließlich Präfix und Doppelpunkt, falls der Knoten ein Element oder ein Attribut ist.
  • local-name(someNode) Gibt nur den lokalen Namen des Knotens zurück, der das Präfix und den Doppelpunkt nicht enthält, falls der Knoten ein Element oder ein Attribut ist.

Daher muss in Situationen, in denen ein Name zu zwei verschiedenen Namespaces gehören kann, die name()Funktion verwendet werden, damit diese Namen noch unterschieden werden können.

Übrigens ist es möglich, beide Funktionen ohne Argument anzugeben :

name() ist eine Abkürzung für name(.)

local-name() ist eine Abkürzung für local-name(.)

Denken Sie schließlich daran, dass nicht nur Elemente und Attribute Namen haben, sondern dass diese beiden Funktionen auch für PIs verwendet werden können und dass diese identisch sind.

Dimitre Novatchev
quelle
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
quelle
Verwenden Sie als gute Vorgehensweise immer normalize-space (), wenn Sie den Wert des Knotens <xsl: value-of select = "normalize-space (.)" /> Abrufen. Dadurch werden die zusätzlichen Leerzeichen gekürzt
SO User
Eine solche Normalisierung / Desinfektion wäre nur erforderlich, wenn sie nicht in der Phase der Eingangserfassung durchgeführt worden wäre. Wenn Sie dies dann tun, müssen Sie es nicht zur Zugriffszeit tun, was normalerweise weitaus häufiger der Fall ist. Man würde es tun, bevor man es zu einer RDB hinzufügt, und ein XML-Dokument ist nur eine andere Datenbank.
Patanjali
9

Für Interessierte gibt es keine:

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

Sie können das Tag / Element jedoch neu erstellen, indem Sie folgende Schritte ausführen:

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

Dies ist nützlich in einer xslt-Vorlage, die beispielsweise die Formatierung von Datenwerten für viele verschiedene Elemente übernimmt. Wenn Sie den Namen des Elements, an dem gearbeitet wird, nicht kennen und dennoch dasselbe Element ausgeben und den Wert bei Bedarf ändern können.

Tim
quelle
6
<xsl:value-of select="name(.)" /> : <xsl:value-of select="."/>
Rowland Shaw
quelle
Warum wurde dies abgelehnt? Zugegeben, man hätte local-name () erwähnen können, wenn man den Namespace nicht auch haben wollte, aber es wäre für die breitere Community nützlich zu erklären, warum dies nicht funktionieren würde.
Rowland Shaw
Möglicherweise konnte das angegebene XML nicht transformiert werden. Der Name (.) ist in diesem Fall "Person". es sollte "Name", "Beruf" und "Hobby" sein.
Ray Lu
@CodeMelt Warum hast du dann die akzeptierte Antwort nicht abgelehnt? Es ist gut, aber noch weniger spezifisch als dieses. Ich habe Rowland Shaws Antwort hochgestimmt, da sie die Antwort auf die Frage liefert. Bitte stimmen Sie nur ab, wenn eine Antwort falsche, falsche oder irreführende Informationen enthält
Dimitre Novatchev
4
Dieses kleine Detail wurde behoben - persönlich denke ich, dass die Leute erklären sollten, warum etwas herabgestuft wird, da es hilft, das kollektive Wissen zu erklären ...
Rowland Shaw
Unser Ruf mag Aufmerksamkeit erregen, aber da sie keine Garantie dafür sind, dass sich das, was wir veröffentlicht haben, lohnt, ist es die Qualität unseres Beitrags, die wirklich zählt. Keine Begründung führt zu Beiträgen von schlechter Qualität.
Patanjali