Subject: Re: [xsl] relative path from one node to another From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Fri, 20 May 2005 05:55:44 +1000 |
I wrote two year ago code that produces the absolute path of a file given its relative path to the absolute path of another file: http://www.stylusstudio.com/xsllist/200501/post21280.html http://groups.google.co.uk/group/microsoft.public.xml/browse_frm/thread/6 be70a1352644ff1/def66c8ed30c8c46?hl=en&lr=&ie=UTF-8&oe=UTF-8&rnum=1&prev=/gro ups%3Fq%3Dnovatchev%2Brelative%2Bpath%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DU TF-8%26selm%3Db8ujil%2524dpl9r%25241%2540ID-152440.news.dfncis.de%26rnum%3D1# def66c8ed30c8c46 Cheers, Dimitre Novatchev. On 5/20/05, Richard Lewis <richardlewis@xxxxxxxxxxxxxx> wrote: > 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()==las t()]" > /> > <!-- 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] relative path from one no, JBryant | Thread | [xsl] How can I use relative reffer, Bovy, Stephen J |
Re: [xsl] apply-templates select an, Wendell Piez | Date | Re: [xsl] nested for-each to create, Rudolf P . Weinmann |
Month |