在XSLT开发中,获取当前节点名和父节点名是处理XML结构时的基础操作,XSLT提供了内置函数和轴表达式来支持这类需求,无需复杂的自定义逻辑即可实现。

获取当前节点名的方法
获取当前节点名可以直接使用XSLT内置的name()函数,该函数会返回当前上下文节点的完整限定名,如果节点没有命名空间,返回的就是节点的本地名称。
如果需要仅获取节点的本地名称(忽略命名空间前缀),可以使用local-name()函数,这两个函数的使用场景有所区别,需要根据实际的XML结构选择。
代码示例:获取当前节点名
假设我们有如下的XML源文件:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<user id="1">
<name>张三</name>
<age>25</age>
</user>
</root>
对应的XSLT样式表获取当前节点名的代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="root/user/*"/>
</xsl:template>
<xsl:template match="*">
<p>当前节点名:<xsl:value-of select="name()"/></p>
<p>当前节点本地名:<xsl:value-of select="local-name()"/></p>
</xsl:template>
</xsl:stylesheet>
上述代码中,模板匹配所有元素节点,通过name()和local-name()分别输出当前节点的完整名称和本地名称,对于上面的XML,处理name和age节点时两个函数的返回结果是一致的。
获取父节点名的方法
获取父节点名需要先通过父轴parent::或者简写形式..定位到父节点,再结合name()或者local-name()函数获取名称。
父轴用于选择当前节点的父节点,每个元素节点最多只有一个父节点,所以使用父轴后返回的结果唯一,不会出现多个节点的情况。
代码示例:获取父节点名
还是使用上面的XML源文件,获取当前节点的父节点名的XSLT代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="root/user/*"/>
</xsl:template>
<xsl:template match="*">
<p>当前节点名:<xsl:value-of select="name()"/></p>
<p>父节点名:<xsl:value-of select="name(parent::*)"/></p>
<p>父节点名(简写形式):<xsl:value-of select="name(..)"/></p>
</xsl:template>
</xsl:stylesheet>
上述代码中,parent::*和..都表示当前节点的父节点,两种写法效果完全一致,将父节点作为参数传入name()函数即可得到父节点的名称。对于name和age节点,父节点都是user,所以输出的父节点名都是user。
注意事项
name()函数如果传入的节点有命名空间,会返回带命名空间前缀的完整名称,比如<ns:user>节点调用name()会返回ns:user。- 如果当前节点是根节点,调用
parent::轴不会返回任何节点,此时name(parent::*)会返回空字符串,使用时需要先判断当前节点是否存在父节点。 - 除了元素节点,
name()函数也可以用于属性节点、文本节点等,但是属性节点的父节点是其所属的元素节点,文本节点的父节点也是包含它的元素节点。
综合示例
下面是一个同时输出当前节点名、父节点名、祖父节点名的完整XSLT示例:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="root/user/*"/>
</xsl:template>
<xsl:template match="*">
<div>
<p>当前节点名:<xsl:value-of select="name()"/></p>
<p>父节点名:<xsl:value-of select="name(..)"/></p>
<p>祖父节点名:<xsl:value-of select="name(../..)"/></p>
</div>
</xsl:template>
</xsl:stylesheet>
处理前面的XML源文件时,对于name节点,输出的祖父节点名就是root,通过连续使用父轴简写形式..可以向上遍历多层节点结构,获取对应层级的节点名称。