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
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format