Apakah ada elemen nama XSLT?

101

Di XSLT ada

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

untuk mendapatkan nilai sebuah elemen, tetapi adakah sesuatu untuk memilih nama-tag dari elemen tersebut?

Dalam situasi seperti ini:

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

Untuk mendapatkan keluaran seperti ini:

name : Robert
profession : programmer
hobby : photography

Tentu saja XSLT di atas tidak dapat dikompilasi karena

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

tidak ada. Tapi bagaimana ini bisa dilakukan?

Robert Gould
sumber
Tag paling relevan untuk pertanyaan ini adalah XPath. Kedua fungsi tersebut adalah fungsi standar XPath dan dapat digunakan dalam ekspresi XPath dalam konteks bahasa hosting apa pun (C #, XSLT, XQuery, ...) Harap
beri
Teks ini: "Dalam XSLT ada <xsd: value-of select =" expression "/>" - mengandung kesalahan. Awalan yang biasanya digunakan untuk instruksi XSLT adalah "xsl". Biasanya saat menggunakan XML Schema kita menggunakan awalan "xsd" atau "xs". Tolong, perbaiki.
Dimitre Novatchev

Jawaban:

156

Ini akan memberi Anda nama elemen saat ini (nama tag)

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

OP-Edit: Ini juga akan melakukan trik:

<xsl:value-of select ="local-name()"/>
Pengguna SO
sumber
12
nama-lokal adalah yang Anda inginkan 9 kali dari 10
annakata
20
local-name adalah sans namespace, inilah mengapa biasanya lebih baik.
Jon W
102

Tidak ada yang menunjukkan perbedaan halus dalam semantik dari fungsi name()dan local-name().

  • name(someNode) mengembalikan nama lengkap node, dan itu termasuk awalan dan titik dua jika node adalah elemen atau atribut.
  • local-name(someNode) mengembalikan hanya nama lokal dari node, dan itu tidak termasuk awalan dan titik dua jika node adalah elemen atau atribut.

Oleh karena itu, dalam situasi di mana sebuah nama mungkin dimiliki oleh dua ruang nama yang berbeda, name()fungsi tersebut harus digunakan agar nama-nama ini tetap dapat dibedakan.

Dan, BTW, dimungkinkan untuk menentukan kedua fungsi tanpa argumen apa pun :

name() adalah singkatan dari name(.)

local-name() adalah singkatan dari local-name(.)

Terakhir , ingatlah bahwa tidak hanya elemen dan atribut yang memiliki nama, kedua fungsi ini juga dapat digunakan pada PI dan keduanya identik).

Dimitre Novatchev
sumber
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
sumber
Sebagai praktik yang baik, selalu gunakan normalize-space () ketika mendapatkan nilai-dari node <xsl: value-of select = "normalize-space (.)" /> Ini akan memangkas ruang ekstra
SO Pengguna
Normalisasi / sanitasi seperti itu hanya dibutuhkan jika tidak ditangani pada tahap pengumpulan masukan. Dengan melakukannya, Anda tidak perlu melakukannya pada waktu akses, yang biasanya jauh lebih sering. Seseorang akan melakukannya sebelum menambahkan ke RDB, dan dokumen xml hanyalah database lain.
Patanjali
9

Bagi yang berminat, tidak ada:

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

Namun Anda dapat membuat ulang tag / elemen dengan membuka:

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

Ini berguna dalam template xslt yang misalnya menangani pemformatan nilai data untuk banyak elemen berbeda. Jika Anda tidak mengetahui nama elemen yang sedang dikerjakan dan Anda masih dapat menampilkan elemen yang sama, dan mengubah nilainya jika perlu.

Tim
sumber
6
<xsl:value-of select="name(.)" /> : <xsl:value-of select="."/>
Rowland Shaw
sumber
Jadi mengapa ini diturunkan sebagai suara? Memang bisa saja menyebutkan nama-lokal () jika Anda tidak menginginkan namespace juga, tetapi akan berguna bagi komunitas yang lebih luas untuk menjelaskan mengapa ini tidak berhasil.
Rowland Shaw
Mungkin, itu tidak bisa mengubah XML yang diberikan. nama (.) akan menjadi "orang" dalam kasus ini. itu harus "nama", "profesi" dan "hobi".
Ray Lu
@CodeMelt Mengapa Anda tidak memberikan suara negatif untuk jawaban yang diterima? Itu bagus, tetapi bahkan kurang spesifik dari yang ini. Saya memilih jawaban Rowland Shaw karena memberikan jawaban atas pertanyaan tersebut. Mohon, pilih negatif hanya jika jawaban berisi informasi yang salah, tidak benar, atau menyesatkan
Dimitre Novatchev
4
Memperbaiki detail kecil itu - secara pribadi, saya pikir orang harus menjelaskan mengapa ada sesuatu yang tidak disukai, karena itu membantu menjelaskan pengetahuan kolektif ...
Rowland Shaw
Reputasi kita mungkin menarik perhatian, tetapi karena itu bukan jaminan bahwa apa yang kita posting berharga, kualitas kontribusi kita yang benar-benar diperhitungkan. Tidak ada alasan yang membuat kontribusi berkualitas buruk.
Patanjali