Dynamic subnavigation-utility
This is an open discussion with 4 replies, filed under XSLT.
Search
So, the root of your problem is that $match-path is a string because you're using concat(), which outputs a string. You can't use a string as an xpath query. I have run into the problem of dynamically generating an xpath query before, and there is no simple solution. You might be able to concat your 'navigation-???' element into a string, then use that directly in the XPath. If that doesn't work, you could possibly test for the name of that element.
so something like this <xsl:with-param name="match-path" select="/data/$navigation-name/entry"/>
or this <xsl:with-param name="match-path" select="/data/*[name()='$navigation-name']/entry"/>
not sure about the name() function, but I think that's right
I was thinking about doing something similar. The trick is to make sure that the XPath expression can be properly evaluated as a node-set. As soon as you turn the expression into a string, it can no longer be evaluated as a node-set and you'll get a "wrong type" error.
So, ashooner was on the right track, but I think some of the details were a little off. A parameter cannot be used as part of the XPath expression:
/data/$navigation-name/entry
And the name()
function is trying to match a string, rather than a parameter, because of the single quotes, and I think the name()
function needs a specific node to return the element name:
name()='$navigation-name'
Try something like this:
<xsl:param name="navigation-entries" select="/data/*[name(.) = concat('navigation",'-',$navigation-name)]/entry"/>
Then you have a valid XPath expression that you can use with the xsl:for-each
instruction:
<xsl:for-each select="$navigation-entries"> <xsl:value-of select="blah"/> </xsl:for-each>
Thanks a bunch, guys!
Bauhouse, you were right. The funny part is, that I have to put this whole /data/*[...]/entry
-thing into the subnavigation
-template. It does not work in the match="page"
-part.
This is the whole working XSLT-Template
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="navigation"> <xsl:apply-templates select="page[not(types/type = 'hidden') and not(types/type = 'admin')]"/> <xsl:if test="/data/events/login-info/@logged-in = 'true'"> <li><a href="{$root}/drafts/">Drafts</a></li> <li><a href="{$root}/symphony/">Admin</a></li> <li><a href="?debug">Debug</a></li> </xsl:if> </xsl:template> <xsl:template match="page"> <ul id="nav-{@handle}"> <li class="rubrik"> <xsl:if test="@handle = $current-page"> <xsl:attribute name="id">subactive</xsl:attribute> </xsl:if> <a href="{$root}/{@handle}/" class="rubrik"> <xsl:value-of select="name"/> </a> <xsl:call-template name="subnavigation"> <xsl:with-param name="match-name" select="@handle"/> </xsl:call-template> </li> </ul> </xsl:template> <xsl:template name="subnavigation"> <xsl:param name="match-path" select="/data/*[name(.) = concat('navigation-',$match-name)]/entry" /> <xsl:if test="count($match-path) != 0"> <ul> <xsl:for-each select="$match-path"> <li> <!-- $content-handle is the URL Parameter --> <xsl:if test="$content-handle = titel/@handle"> <xsl:attribute name="class">active</xsl:attribute> </xsl:if> <a href="{$root}/{$match-name}/{titel/@handle}/"> <xsl:value-of select="titel"/> </a> </li> </xsl:for-each> </ul> </xsl:if> </xsl:template> </xsl:stylesheet>
It looks like I had errors of my own. I see you fixed up the syntax I suggested for the concat function. Glad that's working for you.
Create an account or sign in to comment.
I'm trying to build an efficient navigation-utility with two navigation levels. I have 4 pages (first-level navigation) and 4 sections (each contains entries which are the second-level).
My problem: The
<xsl:with-param>
-part does not work. It outputs the right path, but thefor-each
does not work. When I enter the correct path directly in thefor-each
instead of using theparam
, it does work.Any idea how to fix this? Or is it not possible to create a dynamic
for-each
?snippet from my XML:
snippet from my XSLT