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: XPath grammar questions


Hi Sean,

> Specifically, it's the 'not(*/node())' that I'm having trouble with.
> The XPath spec states that:
>
>   not( boolean ) -> boolean
>
> This would imply that '*/node()' evaluates to a boolean. However, it
> also states that paths such as:
>
>   ancestor::node()
>
> evaluates to a set of matching nodes. Further, I had assumed that
> the path:
>
>   */node()
>
> by itself would also result in a set of nodes.
>
> I have a group of theories about this, but I'm not quite grokking
> the intent of XPath. I don't see how the same path should evaluate
> to two different results. In any case, there have been a number of
> successful implementations of XPath, so I know I'm missing
> something.

Yep. If an XPath function takes a value of a particular type as an
argument, but gets passed a value of a different type, then the actual
value should be converted to the required type automatically. So in
this case, the node set */node() should be converted to a boolean
(through the rules described in the definition of the boolean()
function), and the not() function performed on the result of that.

I don't think that this is particularly clear in the XPath 1.0 Rec,
but the XPath 2.0 WD makes a better job of spelling out what happens.
See http://www.w3.org/TR/xpath20/#id-type-conversions; for XPath 1.0,
you only have to worry about the "fallback conversions".

> The second (and at this point, more critical) problem I'm having is
> with function names. Take:
>
>   [normalize-space(@name)='x']
>
> If you follow the grammar, the evaluation is:
>
>    Predicate->Expr->OrExpr->AndExpr->EqualityExpr->RelationalExpr->
>    AdditiveExpr
>
> at which point it matches the rule:
>
>   AdditiveExpr:: AdditiveExpr '-' MultiplicativeExpr
>
> where you effectively have "normalize" "-" "space(@name)='x'".

In http://www.w3.org/TR/xpath#numbers, there's a note that reads as
follows:

  NOTE: Since XML allows - in names, the - operator typically needs to
  be preceded by whitespace. For example, foo-bar evaluates to a
  node-set containing the child elements named foo-bar; foo - bar
  evaluates to the difference of the result of converting the
  string-value of the first foo child element to a number and the
  result of converting the string-value of the first bar child to a
  number.

Your code needs to take account of the fact that hyphens can appear in
names, and only see the - as a minus sign if it is preceded by
whitespace.

I think that when you're parsing the XPath, you need to follow the
rules about the lexical structure of XPath expressions, at
http://www.w3.org/TR/xpath#exprlex, rather than the XPath grammar
(which focuses on describing how the XPath is evaluated). I believe
that if you follow these rules (which includes a rule saying that the
longest token wins), "normalize-space(@name)='x'" is split into the
tokens:

  "normalize-space" (FunctionName)
  "("
  "@"
  "name" (NameTest)
  ")"
  "=" (Operator)
  "'x'" (Literal)

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]