|
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 |