有 XSLT name-of 元素吗?

在 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"/>

根本不存在,但这怎么可能呢?

165129 次浏览

This will give you the current element name (tag name)

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

OP-Edit: This will also do the trick:

<xsl:value-of select ="local-name()"/>
<xsl:value-of select="name(.)" /> : <xsl:value-of select="."/>
<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>

Nobody did point the subtle difference in the semantics of the functions name() and local-name().

  • name(someNode) returns the full name of the node, and that includes the prefix and colon in case the node is an element or an attribute.
  • local-name(someNode) returns only the local name of the node, and that doesn't include the prefix and colon in case the node is an element or an attribute.

Therefore, in situations where a name may belong to two different namespaces, one must use the name() function in order for these names to be still distinguished.

And, BTW, it is possible to specify both functions without any argument:

name() is an abbreviation for name(.)

local-name() is an abbreviation for local-name(.)

Finally, do remember that not only elements and attributes have names, these two functions can also be used on PIs and on these they are identical).

For those interested, there is no:

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

However you can re-create the tag/element by going:

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

This is useful in an xslt template that for example handles formatting data values for lots of different elements. When you don't know the name of the element being worked on and you can still output the same element, and modify the value if need be.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="person">
<xsl:for-each select="*">
<xsl:text>
</xsl:text>
<xsl:value-of select="local-name()"/> : <xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>