[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Get Position of Node in Ancestor Context

Subject: Re: Get Position of Node in Ancestor Context
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Mon, 10 Mar 2003 17:33:58 +0000
select ancestor
Hi Ted,

> Answered my own question, but would still be interested in knowing
> what others think of this solution...
>
> <xsl:template match="input|select|textarea">
>      <xsl:copy>
>          <xsl:for-each select="@*">
>              <xsl:copy />
>          </xsl:for-each>
>          <xsl:variable name="currElemId" select="@id" />
>          <xsl:attribute name="tabindex"></xsl:attribute>
>          <xsl:for-each  
> select="ancestor::form//select|ancestor::form//input|ancestor::form// 
> textarea">
>              <xsl:if test="not(@type = 'hidden') or @type = 'submit'">
>                  <xsl:if test="@id = $currElemId">
>                      <xsl:attribute name="tabindex"><xsl:value-of  
> select="position()" /></xsl:attribute>
>                  </xsl:if>
>              </xsl:if>
>          </xsl:for-each>
>          <xsl:apply-templates />
>      </xsl:copy>
> </xsl:template>

I think that you'd probably be better off using <xsl:number> here.
Try:

<xsl:template match="input | select | textarea">
  ...
  <xsl:attribute name="tabindex">
    <xsl:number from="form" level="any"
      count="*[self::input or self::select or self::textarea]
              [@type != 'hidden']" />
  </xsl:attribute>
  ...
</xsl:template>

You could use "input[@type != 'hidden'] | select[@type != 'hidden'] |
textarea[@type != 'hidden']" as the value of the count attribute if
you prefer. Note that I dropped the "or @type = 'select'" since any
element with a type attribute equal to 'select' will pass the "@type
!= 'hidden'" test.

> The style sheet basically adds tabindex attributes to all form
> elements. What I'm unhappy with is the value of the select attribute
> of the second for-each element (the one that creates a node set of
> all child elements of a FORM element, regardless of what separates
> them). It seems odd that I have to fully qualify the child element
> I'm looking for, but using ancestor::form//select|input|textarea
> only matches the first element in the list.

Yes; in XPath 2.0, we'll be able to use:

  ancestor::form//(select | input | textarea)

which is a good deal shorter, and likewise with the count attribute
above, we'll be able to do:

  (input | select | textarea)[@type != 'hidden']

> Also, what is the performance impact on setting up such for-each
> loops and is there a faster way to reproduce this node-set in the
> context of the current element (call-template with-param???)?

Numbering based on position within the node tree is always fairly
expensive because it can require a lot of node visits. If the <input>,
<select> and <textarea> elements are siblings, you can use
level="single", which will mean that the processor doesn't have to
look at quite as many nodes. Or you could use a step-by-step recursive
template and pass the current count on from sibling to sibling. But
unless you find performance is really suffering here, I'd stick with
the <xsl:number> solution above.

By the way, rather than:

  <xsl:for-each select="@*"><xsl:copy /></xsl:for-each>

you could just do:

  <xsl:copy-of select="@*" />

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


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


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.