← Back to context

Comment by ndriscoll

3 months ago

It looks like it's related to your setting the default namespace xmlns="http://www.w3.org/1999/xhtml". You could either add a xmlns:example="http://example.org/templates" and then replace `item` with `example:item` everywhere, or you can override the default namespace within your variable's scope:

    <xsl:variable name="nav-menu-items" xmlns="">
        <item href="/">Home</item>
        <item href="/about.xhtml">About</item>
    </xsl:variable>

I think you also don't really need to set the default namespace to xhtml, so I believe you could remove that and not worry about namespaces at all (except for xsl and exsl).

The test is failing because it's `/about.xhtml` in the template but `about` outside. You'd either need to add a name attribute to item to compare on or make it match the href.

That should make your thing work if I haven't fooled myself again. :)

I think you also don't really need to set the default namespace to xhtml

you are right. i removed it, and it works. typical "copy from stackoverflow" error. these namespaces are a mystery and not intuitive at all. i suppose most people don't notice that because it only applies to xml data within the stylesheet. most people won't have that so they won't notice an issue. the less the better.

for the other error, my mistake, duh! in my original example in https://news.ycombinator.com/item?id=44961352 i am comparing $current/@name to a hardcoded value, so if i want to keep that comparison i have to add that value to the nav-menu data. or use a value that's already in there.

i went with adding a name="about" attribute to the nav-menu because it keeps the documents cleaner: <document name="about"> just looks better, and it also allows me to treat it like an ID that doesn't have to match the URL which allows renaming/moving documents around without having to change the content. (they might go from about.xhtml to about/index.xhtml for example)

i am also probably going to use the document() function instead of exsl:node-set() because having the menu data in a separate file in this case is also easier to manage. it's good to know about that option though. being able to iterate over some local data is a really useful feature. i'll keep that around as an example.

the final piece of the puzzle was:

    <xsl:if test="position() != last()"> | </xsl:if>

to put a separator between the items, but not after.

that sorted, now it all works. thank you again.

btw, it's funny that we are turning hackernews into an xsl support forum. i guess i should write all that up into a post some day.

  • Nice. Fwiw I believe you can also use css for the separators if you've put them in a list:

      li + li::before {
        content: " | ";
      }
    

    If xslt survives maybe I should make a forum and/or wiki. Using xslt of course.