これがエレガントと見なされるかどうかはわかりませんが、次のように入力します。
<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回の呼び出し後にループを停止したいと思います。 。