I want to create an XSL file for the following transformation.
I have this XML file
<nodes>
<node url='url1' title='url1'>
<node url='url11' title='url11'>
<node url='url111' title='url111'/>
</node>
<node url='url11' title='url11'/>
<node url='url12' title='url12'/>
<node url='url13' title='url13'>
<node url='url131' title='url131'/>
<node url='url132' title='url132'/>
</node>
</node>
</node>
<node>
<node url='url2' title='url2'>
<node url='url21' title='url21'/></node>
</nodes>
Assuming, that url131 is selected, I want to create this HTML segment
<ul>
<li class='active'><a href='url1'>url1</a>
<ul>
<li><a href='url11'>url11</a></li>
<li><a href='url12'>url12</a></li>
<li class='active'><a href='url13'>url13</a>
<ul>
<li><span>url131</span></li>
<li><a href='url132'>url132<a></li>
</ul>
</li>
</li>
<li><a href='url2'>url2</a><li>
</ul>
In words: the selected element should be created as a span. All parents should be marked as li.active. All sibling of the selected element and its parents stay unmarked. And everything should nested.
In the template I want to use param $self (that can be set from outside) and apply template for the selected url:
<template match="nodes">
<xsl:param name='self'>url131</xsl:param>
<xsl:apply-template select="node()[@url=$self]</xsl:apply-template>
</template>
The template node must process 3 cases, to create LIs with SPANs or ANCORS with or without class .active.
<xls:template match="node">
<!-- todo: choose ... -->
</xsl:template>
But there is the tricky part (for me): will I need some kind of recursion, to go backwards in the tree.
//node[@url=self]/../. for the parent and //node[@url=self]/../../. for the grandparent and the same for their preceding- and following-siblings.
Or should I count the ancestores and use this number as level param. But vars and params can not be used for select, as far as i know.
In the template I want to use param $self (that can be set from outside)
If by "from outside" you mean from outside of the stylesheet, that's not possible. Only global (top-level) parameters can be passed to the stylesheet at runtime.
Consider the following stylesheet:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="utf-8" indent="yes"/>
<xsl:param name="selected-node-url">url142</xsl:param>
<xsl:template match="nodes">
<ul>
<xsl:apply-templates select="node"/>
</ul>
</xsl:template>
<xsl:template match="node">
<li>
<xsl:if test="descendant::node/@url=$selected-node-url">
<xsl:attribute name="class">active</xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="@url=$selected-node-url">
<span><xsl:value-of select="@url"/></span>
</xsl:when>
<xsl:otherwise>
<a href="{@url}"><xsl:value-of select="@url"/></a>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="node">
<ul>
<xsl:apply-templates select="node"/>
</ul>
</xsl:if>
</li>
</xsl:template>
</xsl:stylesheet>
When applied to the following well-formed input:
XML
<nodes>
<node url="url1" title="url1">
<node url="url11" title="url11">
<node url="url111" title="url111"/>
</node>
<node url="url12" title="url12"/>
<node url="url13" title="url13"/>
<node url="url14" title="url14">
<node url="url141" title="url141"/>
<node url="url142" title="url142"/>
</node>
</node>
<node url="url2" title="url2">
<node url="url21" title="url21"/>
</node>
</nodes>
the result will be:
<ul>
<li class="active"><a href="url1">url1</a><ul>
<li><a href="url1">url11</a><ul>
<li><a href="url1">url111</a></li>
</ul>
</li>
<li><a href="url1">url12</a></li>
<li><a href="url1">url13</a></li>
<li class="active"><a href="url1">url14</a><ul>
<li><a href="url1">url141</a></li>
<li><span>url142</span></li>
</ul>
</li>
</ul>
</li>
<li><a href="url1">url2</a><ul>
<li><a href="url1">url21</a></li>
</ul>
</li>
</ul>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.