我想将节点的参数值与其父节点的相同参数值递归连接。
示例,如下:
<node name="root">
<node name="A">
<node name="B">
<node name="C">
<value1>12</value1>
<value2>36</value1>
</node>
</node>
</node>
</node>
应该成为
<node name="root">
<node name="root.A">
<node name="root.A.B">
<node name="root.A.B.C">
<value1>12</value1>
<value2>36</value1>
</node>
</node>
</node>
</node>
我尝试过
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node/@name">
<xsl:choose>
<xsl:when test=". = 'root'">
<xsl:attribute name="name"><xsl:text>webshop</xsl:text></xsl:attribute>
</xsl:when>
<xsl:when test="not(. = 'root')">
<xsl:attribute name="name"><xsl:value-of select="../../@name"/>.<xsl:value-of select="../@name"/></xsl:attribute>
</xsl:when>
</xsl:choose>
</xsl:template>
但是结果不是预期的。我得到的是
<node name="root">
<node name="root.A">
<node name="A.B">
<node name="B.C">
<value1>12</value1>
<value2>36</value1>
</node>
</node>
</node>
</node>
出什么问题了?
答案 0 :(得分:1)
XSLT对输入文档进行操作以生成新的输出文档。输入文档本身将保持不变。当您执行xsl:value-of
(或任何其他XSLT操作)时,将在输入文档中进行选择。因此,您正在向name
属性添加值的事实根本不会影响您的xsl:value-of
语句。
您可以做的是使用一个简单的xsl:for-each
获取所有祖先节点并从中建立name属性:
<xsl:for-each select="ancestor::node">
<xsl:if test="position() > 1">.</xsl:if>
<xsl:value-of select="@name" />
</xsl:for-each>
尝试使用此XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node/@name">
<xsl:attribute name="name">
<xsl:choose>
<xsl:when test=". = 'root'">webshop</xsl:when>
<xsl:otherwise>
<xsl:for-each select="ancestor::node">
<xsl:if test="position() > 1">.</xsl:if>
<xsl:value-of select="@name" />
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
如果您可以使用XSLT 2.0,则可以将xsl:for-each
替换为单个xsl:value-of
<xsl:value-of select="ancestor::node/@name" separator="." />
(在XSLT 1.0中,xsl:value-of
仅输出集合中的第一个节点)