This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RE: Retrieving Full XPATH expression


Ouch!  Definitely a newbe mistake on my part.  I knew about the string
comparison rule but obviously did not fully understand what I was writing.

Based on others' ideas I have since modified it to the following.  The
source documents use a 'name' attribute extensively, so my solution is
customized to my particular project.  It also outputs the attribute value,
again just for debugging purposes.

This does not look particularly efficient to me, but it is used only for
debugging purposed.  Potential performance problems I see include:

	1. Recursive implementation (versus for-each)
	2. Template matching (versus call-template)
	3. Count of the parent's elements (each iteration)
	4. Count of the preceding-siblings (each iteration)

Are these as expensive as they look?

<!-- Root -->
<xsl:template match="/" mode="xpath">
    <xsl:text>/</xsl:text>
</xsl:template>

<!-- Element -->
<xsl:template match="*" mode="xpath">
    <!-- Process ancestors first -->
    <xsl:apply-templates select=".." mode="xpath"/>

    <!-- Output / if not already output by the root node -->
    <xsl:if test="../..">/</xsl:if>

    <!-- Output the name of the element -->
    <xsl:value-of select="name()"/>

    <!-- Add the element's position to pinpoint the element exactly -->
    <xsl:if test="count(../*[name() = name(current())]) > 1">
        <xsl:text>[</xsl:text>
        <xsl:value-of
            select="count(preceding-sibling::*[name() = name(current())]) +
1"/>
        <xsl:text>]</xsl:text>
    </xsl:if>

    <!-- Add 'name' predicate as a hint of which element -->
    <xsl:if test="@name">
        <xsl:text/>[@name="<xsl:value-of select="@name"/>"]<xsl:text/>
    </xsl:if>
</xsl:template>

<!-- Attribute -->
<xsl:template match="@*" mode="xpath">
    <!-- Process ancestors first -->
    <xsl:apply-templates select=".." mode="xpath"/>

    <!-- Output the name of the attribute -->
    <xsl:text/>/@<xsl:value-of select="name()"/>

    <!-- Output the attribute's value as a predicate -->
    <xsl:text/>[.="<xsl:value-of select="."/>"]<xsl:text/>
</xsl:template>

-----Original Message-----
From: owner-xsl-list@lists.mulberrytech.com
[mailto:owner-xsl-list@lists.mulberrytech.com]On Behalf Of Oleg
Tkachenko
Sent: Saturday, August 11, 2001 8:39 AM
To: xsl-list@lists.mulberrytech.com
Subject: RE: [xsl] Retrieving Full XPATH expression


Hello Tom !

> -----Original Message-----
> From: owner-xsl-list@lists.mulberrytech.com
> [mailto:owner-xsl-list@lists.mulberrytech.com]On Behalf Of Tom Landon
> Sent: Friday, August 10, 2001 8:51 PM
> To: xsl-list@lists.mulberrytech.com
> Subject: RE: [xsl] Retrieving Full XPATH expression
>
>
> This is not exactly what you need, but it might be a good starting point:

>         <!-- Attribute node (test if node is in set of parent's
> attributes) -->
>         <xsl:when test="$node = $node/../@*">

Do you realize that this conditional statement can surprisingly evaluate to
true for some element node either ?
An operator "=" applyed to nodes doesn't test one operand to be the same as
another one, it compares their string values instead.
For example, above test will be true for <Book> element:

<Books attr="value" >
	<Book>value</Book>
</Books>

It's a little artificial example, but anyway I don't think it's a good way
to detect attribute node type, instead you can use one of thje following
approaches : count(. | ../@*) = count(../@*) or generate-id() =
generate-id(../@*[name()=name(current())]).

---
Oleg Tkachenko,
Multiconn International


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]