Dans cette transformation 1.0, les catégories sont rassemblées en utilisant simplement la fonction substring-before
y substring-after
.
Pour appliquer cette transformation à votre cas, il vous suffit de définir votre domaine réel dans le fichier xsl:param
et au sein de la xsl:key
.
Notez que votre xml d'entrée est un fragment et qu'il n'est pas clair comment vous avez besoin de gérer le préfixe d'espace de nom. Par conséquent, j'ai testé la transformation sur un échantillon XML sans espaces de noms. Si votre XML source contient des préfixes d'espace de noms, la transformation devrait être ajustée.
XSLT 1.0 testé sous Saxon 6.5.5
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="mydomain" select="'http://mydomain.com/'"/>
<xsl:key name="urlbyloc" match="url" use="substring-before(substring-after(loc,'http://mydomain.com/'),'/')"/>
<xsl:template match="/*">
<ul>
<li><xsl:value-of select="$mydomain"/>
<ul>
<xsl:apply-templates select="url[generate-id()=generate-id(key('urlbyloc', substring-before(substring-after(loc,$mydomain),'/'))[1]) and position()!=1]"/>
</ul>
</li>
</ul>
</xsl:template>
<xsl:template match="url">
<li>
<xsl:value-of select="key('urlbyloc', '')/loc[contains(text(),substring-before(substring-after(current()/loc,$mydomain),'/'))]"/>
<ul>
<xsl:apply-templates select="key('urlbyloc', substring-before(substring-after(loc,$mydomain),'/'))/loc"/>
</ul>
</li>
</xsl:template>
<xsl:template match="loc">
<li><xsl:value-of select="."/></li>
</xsl:template>
<xsl:template match="changefreq|priority"/>
</xsl:stylesheet>
Cette transformation est appliquée sur l'entrée suivante :
<url-set>
<url>
<loc>http://mydomain.com</loc>
<changefreq>weekly</changefreq>
<priority>1.00</priority>
</url>
<url>
<loc>http://mydomain.com/category</loc>
<changefreq>weekly</changefreq>
<priority>0.80</priority>
</url>
<url>
<loc>http://mydomain.com/category/prod1</loc>
<changefreq>weekly</changefreq>
<priority>1.00</priority>
</url>
<url>
<loc>http://mydomain.com/category/prod2</loc>
<changefreq>weekly</changefreq>
<priority>0.80</priority>
</url>
<url>
<loc>http://mydomain.com/othercat</loc>
<changefreq>weekly</changefreq>
<priority>1.00</priority>
</url>
<url>
<loc>http://mydomain.com/othercat/prod1</loc>
<changefreq>weekly</changefreq>
<priority>0.80</priority>
</url>
<url>
<loc>http://mydomain.com/othercat/prod2</loc>
<changefreq>weekly</changefreq>
<priority>0.80</priority>
</url>
</url-set>
Produit :
<ul>
<li>http://mydomain.com/<ul>
<li>http://mydomain.com/category<ul>
<li>http://mydomain.com/category/prod1</li>
<li>http://mydomain.com/category/prod2</li>
</ul>
</li>
<li>http://mydomain.com/othercat<ul>
<li>http://mydomain.com/othercat/prod1</li>
<li>http://mydomain.com/othercat/prod2</li>
</ul>
</li>
</ul>
</li>
</ul>
En utilisant les fonctions définies par l'utilisateur de XSLT 2.0, nous pouvons rendre la transformation encore plus lisible. De plus, vous devrez indiquer votre domaine uniquement dans les paramètres initiaux, car 2.0 xsl:key
supporte les références variables.
XSLT 2.0 testé sous Saxon-B 9.0.0.4J
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:empo="http://stackoverflow.com/users/253811/empo"
exclude-result-prefixes="empo">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:param name="mydomain" select="'http://mydomain.com/'"/>
<xsl:function name="empo:get-category">
<xsl:param name="loc"/>
<xsl:param name="mydomain"/>
<xsl:value-of select="substring-before(substring-after($loc,$mydomain),'/')"/>
</xsl:function>
<xsl:key name="urlbyloc" match="url" use="empo:get-category(loc,$mydomain)"/>
<xsl:template match="/*">
<ul>
<li><xsl:value-of select="$mydomain"/>
<ul>
<xsl:apply-templates select="url[generate-id()=generate-id(key('urlbyloc', empo:get-category(loc,$mydomain))[1]) and position()!=1]"/>
</ul>
</li>
</ul>
</xsl:template>
<xsl:template match="url">
<li>
<xsl:value-of select="key('urlbyloc', '')/loc[contains(text(),empo:get-category(current()/loc,$mydomain))]"/>
<ul>
<xsl:apply-templates select="key('urlbyloc',empo:get-category(loc,$mydomain))/loc"/>
</ul>
</li>
</xsl:template>
<xsl:template match="loc">
<li><xsl:value-of select="."/></li>
</xsl:template>
<xsl:template match="changefreq|priority"/>
</xsl:stylesheet>