4 ms·
unfortunately i hit another snag: https://stackoverflow.com/questions/3884927/how-to-use-xsl-variable-in-xslapply-templates#3885071 https://stackoverflow.com/qu
by em-bee 1y ago
unfortunately i hit another snag: https://stackoverflow.com/questions/3884927/how-to-use-xsl-variable-in-xslapply-templates#3885071 https://stackoverflow.com/questions/3884927/how-to-use-xsl-v...
nodes you output don't have type "node-set" - instead, they're what is called a "result tree fragment". You can store that to a variable, and you can use that variable to insert the fragment into output (or another variable) later on, but you cannot use XPath to query over it.
the xsl documentation https://www.w3.org/TR/xslt-10/#variables https://www.w3.org/TR/xslt-10/#variables says:
Variables introduce an additional data-type into the expression language. This additional data type is called result tree fragment. A variable may be bound to a result tree fragment instead of one of the four basic XPath data-types (string, number, boolean, node-set). A result tree fragment represents a fragment of the result tree. A result tree fragment is treated equivalently to a node-set that contains just a single root node. However, the operations permitted on a result tree fragment are a subset of those permitted on a node-set. An operation is permitted on a result tree fragment only if that operation would be permitted on a string (the operation on the string may involve first converting the string to a number or boolean). In particular, it is not permitted to use the /, //, and [] operators on result tree fragments.
so using apply-templates on a variable doesn't work. this is actually where i got stuck before. i just was not sure because i could not verify that everything else was correct.
i wonder if it is possible to load the menu from a second document: https://www.w3.org/TR/xslt-10/#document https://www.w3.org/TR/xslt-10/#document
edit: it is!
<xsl:apply-templates select="document('nav-menu.xml')/menu">
now i just need to finetune this because somehow the $current param fails now.
- ndriscoll 1y agoAh, I could've sworn that it worked in some version of the page that I tried as I iterated on things, but it could be that the browser just froze on my previously working page and I fooled myself. Adding xmlns:exsl="http://exslt.org/common http://exslt.org/common" to your xsl:stylesheet and doing select="exsl:node-set($nav-menu-items)/item" seems to work on both Chrome and Librewolf.
- em-bee 1y agotried that, getting an empty match. here is the actual stylesheet i am using: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:exsl="http://exslt.org/common" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"> <xsl:output method="html"/> <xsl:variable name="nav-menu"> <item href="/">Home</item> <item href="/about.xhtml">About</item> </xsl:variable> <xsl:template match="document"> <html> <head> <meta charset="utf-8" /> <title><xsl:value-of select="title" /></title> <link rel="stylesheet" type="text/css" href="site.css" /> </head> <body> <!-- <xsl:apply-templates select="document('nav-menu.xml')/menu"> --> <xsl:apply-templates select="exsl:node-set($nav-menu)/item"> <xsl:with-param name="current" select="@name"/> </xsl:apply-templates> <xsl:apply-templates select="content" /> </body> </html> </xsl:template> <xsl:template match="item"> <xsl:param name="current"/> <xsl:choose> <xsl:when test="@href=$current"> <a class="selected"><xsl:apply-templates/></a> </xsl:when> <xsl:otherwise> <a href="{@href}"><xsl:apply-templates/></a> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="content"> <xsl:apply-templates select="@*|node()" /> </xsl:template> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> documents look like this: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <?xml-stylesheet type="text/xsl" href="site.xsl"?> <document name="about"> <title>About Us</title> <content> html content here, to be inserted without change </content> </document> if i use the document() function, with nav-menu.xml looking like this: <menu> <item href="/">Home</item> <item href="/about.xhtml">About</item> </menu> then i get the menu items, but the test <xsl:when test="@href=$current"> fails
- ndriscoll 1y agoIt looks like it's related to your setting the default namespace xmlns="http://www.w3.org/1999/xhtml http://www.w3.org/1999/xhtml". You could either add a xmlns:example="http://example.org/templates 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. :)