我有一个像这样的xml结构:
<nav>
<group>
<menu>
<item>
<nav>
<item></item>
</nav>
</item>
</menu>
</group>
<group>
<item></item>
<item></item>
</group>
</nav>
我想使用XSLT 1.0获得此结果:
<nav id="1">
<group>
<menu id="1-1">
<item id="1-1-1">
<nav id="1-1-1-1">
<item id="1-1-1-1-1"></item>
</nav>
</item>
</menu>
</group>
<group>
<item id="1-2"></item>
<item id="1-3"></item>
</group>
</nav>
这有点棘手。
我一直在尝试使用xsl:number,但它坚持要包含&#39; group&#39;在编号中。
提前致谢。
答案 0 :(得分:1)
现在这个答案已经完成并满足您所需的输出要求,但我想它仍然不完美。但是,这是给定数据可以实现的最佳答案:
XSLT-1.0:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:strip-space elements="*" />
<!-- modified identity transform -->
<xsl:template match="@*|node()">
<xsl:variable name="depth" select="count(ancestor::*) - count(ancestor::group)" />
<xsl:element name="{name()}">
<xsl:if test="not(../group)">
<xsl:attribute name="id">
<xsl:call-template name="num">
<xsl:with-param name="cnt" select="$depth" />
</xsl:call-template>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template name="num">
<xsl:param name="cnt" />
<xsl:choose>
<xsl:when test="self::item and $cnt = 0">
<xsl:variable name="itm" select="count(preceding::item)" />
<xsl:variable name="grp" select="count(preceding::group) = 0" />
<xsl:value-of select="$itm + $grp" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'1'" />
</xsl:otherwise>
</xsl:choose>
<xsl:if test="$cnt != 0">
<xsl:value-of select="'-'"/>
<xsl:call-template name="num">
<xsl:with-param name="cnt" select="$cnt - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这个XSLT的结果是:
<?xml version="1.0"?>
<nav id="1">
<group>
<menu id="1-1">
<item id="1-1-1">
<nav id="1-1-1-1">
<item id="1-1-1-1-1"/>
</nav>
</item>
</menu>
</group>
<group>
<item id="1-2"/>
<item id="1-3"/>
</group>
</nav>
根据需要。