Subject: [xsl] relative path from one node to another From: "Richard Lewis" <richardlewis@xxxxxxxxxxxxxx> Date: Thu, 19 May 2005 18:37:22 +0100 |
Hi there, I would have thought that the answer to this would be simple but I can't work it out. I have a document which represents an entire website and contains structural 'section' elements and lots of other mixed content. These 'section' elements all have a unique 'id' field and come in two flavors: their 'display' attributes contain either the value 'page', meaning that they should be rendered in a separate result document, or 'inline', meaning that they should be rendered as part of the content of their ancestor 'page' section. Whenever a 'page' section element is nested inside another 'page' section element, this relationship is reflected in the result documents by a corresponding directory structure: example document: <document> <section id="index" display="page"> <!-- content --> </section> <section id="staff" display="page"> <section id="permanent" display="page"> <section id="tom" display="page"> <!-- content --> </section> <section id="dick" display="page"> <!-- content --> </section> <section id="harry" display="page"> <!-- content --> </section> </section> <section id="permanent" display="page"> <section id="jim" display="inline"> <!-- content --> </section> <section id="jon" display="inline"> <!-- content --> </section> </section> </section> <section id="research" display="page"> <section id="ai" display="inline"> <!-- content --> </section> <section id="algorithms" display="inline"> <!-- content --> </section> </section> </document> should produce following result documents set: ROOT/ +-- staff/ +-- permanent/ +-- tom.html +-- dick.html +-- harry.html +-- temporary.html +-- index.html +-- research.html I've written an xsl function which correctly calculates the necessary file name to pass to xsl:result-document within the 'section' template so the above example works so far. Also in my document I have a number of 'link' elements which can either have an 'href' attribute and link to an external resource or they can have a 'section' attribute which is the 'id' value of a 'section' element; in this case, the link element should produce an HTML <a> tag with an 'href' value of the relative path from the result document in which the link element occurs to the result document of the given 'section' element. There doesn't seem to be an XPath function to calculate the relative path from one node to another (though even if there were it wouldn't solve the problem as I need it to consider only those nodes with name 'section' and '@display="page"' as 'path nodes'). I have tried writing a function which takes two 'id' values as arguments and calculates the relative result document filesystem path between the two nodes which they represent but I haven't had much luck! This is what I've got so far: <xsl:function name="my:relative-path"> <xsl:param name="from-id" /> <xsl:param name="to-id" /> <!-- find the descendant 'section' node with @display='page' closest to the 'section' node with @id=$from-id: --> <xsl:variable name="from-node" select="if ($from-id='ROOT') / else //*[@id=$from-id]//ancestor-or-self::section[@display='page'][position()==last()]" /> <!-- find the descendant 'section' node with @display='page' closest to the 'section' node with @id=$to-id: --> <xsl:variable name="to-node" select="if ($to-id='ROOT') / else //*[@id=$to-id]//ancestor-or-self::section[@display='page'][position()==last()]" /> <!-- find the first common ancestor 'section' node (or root node) --> <xsl:for-each select="$from-node//ancestor-or-self::section[@display='page'] | /"> <xsl:variable name="ifrom" select="." /> <xsl:for-each select="$to-node//ancestor-or-self::section[@display='page'] | /"> <xsl:if test=".=$ifrom"><xsl:variable name="common-ancestor" select="." /></xsl:if> </xsl:for-each> </xsl:for-each> <!-- count the number of 'section' nodes from $common-ancestor to $from-node (along the descendant axis)--> <!-- return that many '../' strings --> <!-- HOW? --> <!-- for each 'section' node from $to-node to $common-ancestor (along the ancestor axis) --> <!-- return concat(@id, '/') --> <!-- HOW? --> </xsl:function> (I haven't tested this at all yet. I am right in thinking that the xsl:function element won't know about the current source tree? And that, consequently, I won't be able to use '/' or '//*[@id...' in the first two xsl:variable elements?) As you can see, I don't know how to implement this algorithm. Furthermore, I don't even know if this algorithm is best solution to the problem! Any help or ideas would be very much appreciated! Thanks very much, Richard
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] How to reference nested c, Michael . Giroux | Thread | Re: [xsl] relative path from one no, JBryant |
[xsl] How to reference nested compl, Michael . Giroux | Date | Re: [xsl] XPath query syntax, jpk |
Month |