- From: <pratik.datta@oracle.com>
- Date: Fri, 04 Sep 2009 11:35:58 -0700
- To: XMLSec WG Public List <public-xmlsec@w3.org>
- Message-ID: <4AA15E0E.9010909@oracle.com>
To define the Streamable XPath subset more formally, I have taken the grammar from the XPath 1.0 spec, and shown the modifications to it. Additions are in green, and deletions are in red strikeout. I have kept the rule numbers the same, so that we can correlate with the spec. I am planning to put this in the draft spec. Grammer Explanation [0a] IncludedXPath ::= ( LocationPath '|' )* LocationPath [0b] ExcludedXPath ::= ( LocationPath '|' )* LocationPath The Included and Excluded Xpath do not use the generic XPath Expr. Instead they are just a union of LocationPath. There is a slight difference between IncludedXPath and ExcludedXPath, ExcludedXpath can select attributes and element, whereas IncludedXPath can only select elements. [1] LocationPath ::= RelativeLocationPath | AbsoluteLocationPath [2] AbsoluteLocationPath ::= '/' RelativeLocationPath? | AbbreviatedAbsoluteLocationPath [3] RelativeLocationPath ::= Step | RelativeLocationPath '/' Step ( StepNoPredicate '/')* Step | AbbreviatedRelativeLocationPath * RelativeLocationPath is not allowed, only Absolute is allowed. This is because if you use relative, it would probably mean relative to the <Signature> element, and then you would have to support the ancestor axis to reach the other nodes, but that axis is not streamable. * Only the last Step can have a predicate. So I have created a non-terminal "StepNoPredicate" [4] Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep [4a] StepNoPredicate ::= AxisSpecifier NodeTest | AbbreviatedStep [4b] StepAttributeOnly ::= 'attribute' '::' NameTest | '@' '::' NameTest Added two new versions of Step. One is a Step with no Predicate, and the other is a step attribute only e.g. in this XPath expression /doc/chapter[@type="warning"] * doc" is StepNoPredicate * chapter[@type="warning"] is Step * @type is StepAttributeOnly [5] AxisSpecifier ::= AxisName '::' | AbbreviatedAxisSpecifier unchanged [6] AxisName ::= 'ancestor' | 'ancestor-or-self' | 'attribute' | 'child' | 'descendant' | 'descendant-or-self' | 'following' | 'following-sibling' | 'namespace' | 'parent' | 'preceding' | 'preceding-sibling' | 'self' All the non streamable axes have been removed - ancestor, ancestor-or-self, following, following-sibling, namespace, parent, preceding, preceding-sibling [7] NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' processing instruction test is not allowed. only the node() nodetest is allowed, not comment(), text() and processing-instruction() [8] Predicate ::= '[' PredicateExpr ']' [9] PredicateExpr ::= Expr unchanged but the definition of Expr has changed, so it is only a additive/relative expressions of StepAttributeOnly and Literals. [10] AbbreviatedAbsoluteLocationPath ::= '//' RelativeLocationPath [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step [12] AbbreviatedStep ::= '.' | '..' [13] AbbreviatedAxisSpecifier ::= '@'? unchanged [14] Expr ::= OrExpr [15] PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall unchanged [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument )* )? ')' [17] Argument ::= Expr unchanged [18] UnionExpr ::= PathExpr | UnionExpr '|' PathExpr [19] PathExpr ::= LocationPath | FilterExpr | FilterExpr '/' RelativeLocationPath | FilterExpr '//' RelativeLocationPath [20] FilterExpr ::= PrimaryExpr | FilterExpr Predicate UnionExpr, PathExpr and FilterExpr have been removed. [21] OrExpr ::= AndExpr | OrExpr 'or' AndExpr [22] AndExpr ::= EqualityExpr | AndExpr 'and' EqualityExpr [23] EqualityExpr ::= RelationalExpr | EqualityExpr '=' RelationalExpr | EqualityExpr '!=' RelationalExpr [24] RelationalExpr ::= AdditiveExpr | RelationalExpr '<' AdditiveExpr | RelationalExpr '>' AdditiveExpr | RelationalExpr '<=' AdditiveExpr | RelationalExpr '>=' AdditiveExpr unchanged [25] AdditiveExpr ::= MultiplicativeExpr | AdditiveExpr '+' MultiplicativeExpr | AdditiveExpr '-' MultiplicativeExpr [26] MultiplicativeExpr ::= UnaryExpr | MultiplicativeExpr MultiplyOperator UnaryExpr | MultiplicativeExpr 'div' UnaryExpr | MultiplicativeExpr 'mod' UnaryExpr [27] UnaryExpr ::= UnionExpr PrimaryExpr | StepAttributeOnly | '-' UnaryExpr The unaryExpr is changed to only allow a PrimaryExpr or StepAttributeOnly [28] ExprToken ::= '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::' | NameTest | NodeType | Operator | FunctionName | AxisName | Literal | Number | VariableReference [29] Literal ::= '"' [^"]* '"' | "'" [^']* "'" [30] Number ::= Digits ('.' Digits?)? | '.' Digits [31] Digits ::= [0-9]+ [32] Operator ::= OperatorName | MultiplyOperator | '/' | '//' | '|' | '+' | '-' | '=' | '!=' | '<' | '<=' | '>' | '>=' [33] OperatorName ::= 'and' | 'or' | 'mod' | 'div' [34] MultiplyOperator ::= '*' [35] FunctionName ::= QName - NodeType [36] VariableReference ::= '$' QName [37] NameTest ::= '*' | NCName ':' '*' | QName [38] NodeType ::= 'comment' | 'text' | 'processing-instruction' | 'node' [39] ExprWhitespace ::= S unchanged, expect for the NodeTest Node set functions * last() * position() * count(nodeset) * id() * local-name(nodeset) * namespace-uri(nodeset) * name(nodeset) String functions * string(object) * concat(string, string, string*) * starts-with(string, string) * contains(string, string) * substring-before(string, string) * substring-after(string, string) * substring(string, number, number) * string-length(string?) * normalize-space(string?) Boolean functions * boolean(object) * true() * fakse() * lang(string) Number functions * number(object?) * sum(node-set) * floor(number) * ceiling(number) * round(number) Note: As mentioned before, only the last Step can have a Predicate, and this predicate's expression can only involve attribute nodes of the current element. Functions can only be used inside this last step's predicate, and this function can only accept a single attribute as an argument. There is no way to use element names, text nodes, comments and processing instructions in functions. The "string-value" become just the attributes value. All functions involving context position and context size are not supported i.e.. last, position, count or their shortcut versions e.g. foo[1]. the streaming parser cannot maintain counts. String, number and boolean functions are all supported. Also it might be easier to understand this with some examples, of what is a valid streamable XPath and what is not. *Non streamable XPaths* Reason .//para Relative paths are not allowed. /doc/chapter[5]/section[2] Predicates are only allowed in the last step. Also the position() function is not allowed //chapter[title="Introduction"] Cannot use a child element in the predicate. Only attributes are allowed in predicate. following-sibling::chapter[position()=1] following-sibling axis is not allowed., position function is not allowed, relative path is not allowed ../title parent axis is not allowed, relative paths are not allowed. id("foo") id function is not allowed. functions can only be used inside a predicate /doc/chapter/child::text() Not allowed to select text nodes. *Streamable XPath examples* * //olist/item * //para[@type="warning"] * //employee[@secretary and @assistant] * /soap:Envelope/soap:Header/*[@actor = "msh"] * /*/para * //para/@type (this XPath is valid in ExcludedXpath, but not in IncludedXpath) Pratik
Received on Friday, 4 September 2009 18:37:29 UTC