我不知道这是否会被认为是优雅的,但是有了这个输入:
<root>
<categories>
<category id="1" parent="0">Configurations</category>
<category id="11" parent="13">LCD Monitor</category>
<category id="12" parent="13">CRT Monitor</category>
<category id="13" parent="1">Monitors</category>
<category id="123" parent="122">Printer</category>
</categories>
<products>
<product>
<category>12</category>
</product>
<product>
<category>11</category>
</product>
</products>
</root>
这个 XSLT:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<root>
<xsl:apply-templates select="//product"/>
</root>
</xsl:template>
<xsl:template match="product">
<product>
<path>
<xsl:call-template name="catwalk">
<xsl:with-param name="id"><xsl:value-of select="category"/>
</xsl:with-param>
</xsl:call-template>
</path>
</product>
</xsl:template>
<xsl:template name="catwalk">
<xsl:param name="id"/>
<xsl:if test="$id != '0'">
<xsl:call-template name="catwalk">
<xsl:with-param name="id"><xsl:value-of select="//category[@id = $id]/@parent"/>
</xsl:with-param>
</xsl:call-template>
<xsl:value-of select="//category[@id = $id]"/><xsl:text>/</xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
会给你这个输出:
<?xml version="1.0" encoding="utf-8"?>
<root>
<product>
<path>Configurations/Monitors/CRT Monitor/
</path>
</product>
<product>
<path>Configurations/Monitors/LCD Monitor/
</path>
</product>
</root>
路径仍然有一个额外的尾部斜杠,您需要另外一点条件 XSLT 以使斜杠仅在您不在第一级时发出。
您的类别层次结构正确至关重要,否则您的转换很容易陷入无限循环,只有在内存不足时才会停止。如果我在真实系统中实现类似的东西,我会很想向 catWalk 模板添加一个参数,该参数在每次调用时递增并将其添加到测试中,以便在 10 次调用后停止循环,无论是否找到父级.