boen_robot Posted May 28, 2006 Share Posted May 28, 2006 Hello. I have a main XSLT which includes another one for the menu. The data for the menu is in it's own XML file. That said, I need to use the document() function in order to transform the menu data and still transform the main data. So far, so good. But for some reason the function isn't working as I though it would.The important part of the main XSLT: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:include href="navigation.xsl"/><xsl:template match="/">...<div id="left"><xsl:call-template name="navigation"/></div>...</xsl:template></xsl:stylesheet> Where navigation.xsl is <?xml version="1.0" encoding="windows-1251"?><!-- DWXMLSource="navigation.xml" --><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:variable name="Nav" select="'navigation.xml'"/><xsl:template name="navigation"><xsl:for-each select="document($Nav,/)"><xsl:call-template name="menu" /></xsl:for-each></xsl:template><xsl:template name="menu"><xsl:for-each select="document($Nav,menu)"><ul> <xsl:for-each select="document($Nav,item)"> <li> <a href="{document($Nav,link)}"> <xsl:value-of select="document($Nav,menu/item/title)"/> </a> </li> <xsl:if test="document($Nav,menu)"> <xsl:call-template select="menu"/> </xsl:if> </xsl:for-each></ul></xsl:for-each></xsl:template></xsl:stylesheet> And the problematic XML for which I need the document function. <?xml version="1.0" encoding="windows-1251"?><menu> <item> <title>Home</title> <link>#</link> </item> <item> <title>Products</title> <link>#</link> <menu> <!-- Contains other items with a title, link and possibly other nested menu --> </menu> </item></menu> The reason I'm having a template navigation to call the second template menu is that menu is suppose to be repeated for every nested menu.The problem is that for some reason, every document() function below <xsl:for-each select="document($Nav,menu)"> is treated as a relative path to the root of the document, not the previously selected by this for-each path (in this case- menu). It gets worse. Because of call-template which selects itself and because the root <menu> would always exist in the whole file, the template is being looped infinetly, thus eventually causing IE to crash. At the same time, FF is being wise enough to not actually select anything below <xsl:for-each select="document($Nav,menu)"> My desired output is something like this: <ul> <li> <a href="#>Home</a> </li> <li> <a href="#">Products</title> <ul> <!-- Contains other "li"s with an "a" with attribute "href", and possibly other nested "ul" --> </ul> </li></ul> Any ideas?P.S. I can't believe I'm having theese issues. In moments like this I really hope I'm not the only person here interested in XSLT. Link to comment Share on other sites More sharing options...
asylum Posted May 28, 2006 Share Posted May 28, 2006 This is just an idea but do you think since the template 'menu' is being called with a document tree from an external document that you no longer need to reference that document and you only need to provide relative uri's as though the document were referencing it as it's own stylesheet?e.g. <?xml version="1.0" encoding="windows-1251"?><!-- DWXMLSource="navigation.xml" --><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:variable name="Nav" select="'navigation.xml'"/><xsl:template name="navigation"><xsl:for-each select="document($Nav,/)"><xsl:call-template name="menu" /></xsl:for-each></xsl:template><xsl:template name="menu"><xsl:for-each select="menu">.........</xsl:for-each></xsl:template></xsl:stylesheet> Link to comment Share on other sites More sharing options...
boen_robot Posted May 28, 2006 Author Share Posted May 28, 2006 Hm, no. That would result in an empty node set, because it would mean processing the main document. Or if I must say it with words:For each root element in the document $Nav, which happens to be navigation.xml in the same folder, call the template called "menu" which would do something for each "menu" found in the current position of the main document, and that position happens to be the root of the main document (see the template calling navigation). Link to comment Share on other sites More sharing options...
asylum Posted May 30, 2006 Share Posted May 30, 2006 problem solved Link to comment Share on other sites More sharing options...
boen_robot Posted May 30, 2006 Author Share Posted May 30, 2006 It almost works for me. The links are generated fine and the content shows but for some reason the <ul> and/or <li>s are not created, thus leaving all the links "floating". Here's the new code after your suggested alterations: <?xml version="1.0" encoding="windows-1251"?><!-- DWXMLSource="navigation.xml" --><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:variable name="Nav" select="'navigation.xml'"/><xsl:template name="navigation"> <xsl:for-each select="document($Nav)/menu"> <xsl:call-template name="menu" /> </xsl:for-each></xsl:template><xsl:template name="menu" match="menu"> <ul> <xsl:for-each select="item"> <li> <a href="{link}"> <xsl:value-of select="title"/> </a> <xsl:if test="menu"> <xsl:apply-templates select="menu"/> </xsl:if> </li> </xsl:for-each> </ul></xsl:template></xsl:stylesheet> And my main XSLT's source could be seen here.This odd behaviour starts when call-template is first used. Manually creating links in lists gives proper results when inserted after <xsl:call-template name="navigation"/> but when inserted in the templates navigation or menu, it gives the same odd results. Cold Fusion's parser gives errors. Any clue on what I might have done wrong? Link to comment Share on other sites More sharing options...
asylum Posted May 30, 2006 Share Posted May 30, 2006 Just a thought but you should make sure your pages by themselves are valid xml. By that I mean the .xml and the appropriate schema or dtd file parse correctly.I'm not sure what else besides that I'll have to take a look a little later Link to comment Share on other sites More sharing options...
boen_robot Posted June 11, 2006 Author Share Posted June 11, 2006 I know I'm being pretty noobish for asking this, but could you please re-post the code you made earlier, only this time as a in your post for later examination. Scince I last checked, you've started developing your code, making it even harder for me to try and figure out what I have done wrong. I'm thinking of copy&paste your example and edit from it on, to see where it all goes wrong (that's what I should have done from the start, only I just realized that), but I would prefer to do this with the most simple example possible. I'm trying to reach a new skill level here after all . Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now