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]
Other format: [Raw text]

Re: first of type element position


Hi Sébastien,

> but is it possible with indicating the position and the element name
> in the test like this:
> <xsl:if test=".[self::TOC.SECT][position()!=1]">

That syntax isn't allowed because you can't use predicates with the
abbreviation '.'. You could use:

  <xsl:if test="current()[self::TOC.SECT][position() != 1]">
    ...
  </xsl:if>

But it wouldn't do you much good! :) The current() function returns a
node set containing one node, the current node. The [self::TOC.SECT]
predicate filters that node set to only those nodes that are TOC.SECT
elements. Since you're in a template that matches TOC.SECT elements,
you know that it must be a TOC.SECT element anyway, so the test is
equivalent to:

  <xsl:if test="current()[position() != 1]">
    ...
  </xsl:if>

The [position() != 1] filters the node set so that it contains all but
the first node in the original node set. The node set can only have one
node in it anyway - the current node - so you always end up with the
empty node set.

In the context of the test attribute of an xsl:if, the expression gets
converted into a boolean. An empty node set converts to boolean false,
so the test is equivalent to:

  <xsl:if test="false()">
    ...
  </xsl:if>

So the content of the xsl:if will never be processed, and you may as
well delete the xsl:if altogether! :)

But yes, you could use the same kind of principal and test whether the
TOC.SECT element that you're looking at is the same as the first
TOC.SECT element child of this TOC.SECT element's parent with:

  <xsl:if test="generate-id(../TOC.SECT[1]) != generate-id()">
    ...
  </xsl:if>

or:

  <xsl:if test="count(. | ../TOC.SECT[1]) != 1">
    ...
  </xsl:if>

if you prefer.
  
> i have already use *[self::TOC.SECT][1] (with the same kind of
> problem) in a template match and it worked well.

Ahh, but match attributes work differently from test/select attributes
because they contain patterns rather than expressions. Plus the path
is different anyhow because you're using * (which in the context of an
expression would select all the child elements) rather than current()
(which selects the current node).

The pattern *[self::TOC.SECT][1] is exactly equivalent to the pattern:

  TOC.SECT[1]

When the processor is told to apply templates to a node, and comes
across this pattern, it checks to see if the node is a TOC.SECT
element that is the first TOC.SECT element child of its parent node.
If it is, then it uses the template to process the node.

Cheers,

Jeni

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


 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]