I don't know whether this would be considered elegant, but with this input:
<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>
This 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>
Will give you this output:
<?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>
The paths still have an extra trailing slash, you'd need another little bit of conditional XSLT to make the slash only get emitted when you aren't at the first level.
It is vital that you category hierarchy is correct, otherwise your transform can easily get into an endless loop that will only stop when it runs out of memory. If I was implementing something like this in a real system I'd be tempted to add a parameter to the catWalk template that incremented on each call and add it to the test so it stopped looping after 10 calls whether or not the parent had been found.