Path expressions ================ In the public API, especially for aug_match and aug_get, tree nodes can be identified with a powerful syntax, that is modelled on the XPath syntax for XML documents. In the simplest case, a path expression just lists a path to some node in the tree, for example, /files/etc/hosts/1/ipaddr If multiple nodes have the same label, one of them can be picked out by providing its position, either counting from the first such node (at position 1) or counting from the end. For example, the second alias of the first host entry is /files/etc/hosts/1/alias[2] and the penultimate alias is /files/etc/hosts/1/alias[last() - 1] For /etc/hosts, each entry can be thought of as a primary key (the ipaddr) and additional attributes relating to that primary key, namely the canonical host name and its aliases. It is therefore natural to refer to host entries by their ipaddr, not by the synthetic sequence number in their path. The canonical name of the host entry with ipaddr 127.0.0.1 can be found with /files/etc/hosts/*[ipaddr = "127.0.0.1"]/canonical or, equivalently, with /files/etc/hosts/*/canonical[../ipaddr = "127.0.0.1"] The canonical names of all hosts that have at least one alias: /files/etc/hosts/*/canonical[../alias] It is also possible to search bigger parts of the tree by using '//'. For example, all nodes called 'ipaddr' underneath /files/etc can be found with /files/etc//ipaddr This is handy for finding errors reported by Augeas underneath /augeas: /augeas//error A lazy way to find localhost is /files/etc//ipaddr[. = '127.0.0.1'] The vardir entry in the main section of puppet.conf is at /files/etc/puppet/puppet.conf/section[. = "main"]/vardir All pam entries that use the system-auth module: /files/etc/pam.d/*[.//module = "system-auth"] More examples can be found in tests/xpath.tests One further extension that might be useful is to add boolean operators for predicates, so that we can write /files/etc/hosts/ipaddr[../alias = 'localhost' or ../canonical = 'localhost'] Grammar for path expressions ============================ Formally, path expressions are generated by this grammar. The grammar uses nonterminals from the XPath 1.0 grammar to point out the similarities between XPath and Augeas path expressions. Unfortunately, the production for PathExpr is ambiguous, since Augeas is too liberal in what it allows as labels for tree nodes: the expression '42' can either be the number 42 (a PrimaryExpr) or the RelativeLocationPath 'child::42'. The reason for this ambiguity is that we allow node names like '42' in the tree; rather than forbid them, we resolve the ambiguity by always parsing '42' as a number, and requiring that the user write the RelativeLocationPath in a different form, e.g. 'child::42' or './42'. LocationPath ::= RelativeLocationPath | AbsoluteLocationPath AbsoluteLocationPath ::= '/' RelativeLocationPath? | AbbreviatedAbsoluteLocationPath AbbreviatedAbsoluteLocationPath ::= '//' RelativeLocationPath RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | AbbreviatedRelativeLocationPath AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step Step ::= AxisSpecifier NameTest Predicate* | '.' | '..' AxisSpecifier ::= AxisName '::' | <epsilon> AxisName ::= 'ancestor' | 'ancestor-or-self' | 'child' | 'descendant' | 'descendant-or-self' | 'parent' | 'self' | 'root' NameTest ::= '*' | Name Predicate ::= "[" Expr "]" * PathExpr ::= LocationPath | FilterExpr | FilterExpr '/' RelativeLocationPath | FilterExpr '//' RelativeLocationPath FilterExpr ::= PrimaryExpr Predicate PrimaryExpr ::= Literal | Number | FunctionCall | VariableReference | '(' Expr ')' FunctionCall ::= Name '(' ( Expr ( ',' Expr )* )? ')' Expr ::= EqualityExpr EqualityExpr ::= RelationalExpr (EqualityOp RelationalExpr)? | ReMatchExpr ReMatchExpr ::= RelationalExpr MatchOp RelationalExpr MatchOp ::= "=~" | "!~" EqualityOp ::= "=" | "!=" RelationalExpr ::= AdditiveExpr (RelationalOp AdditiveExpr)? RelationalOp ::= ">" | "<" | ">=" | "<=" AdditiveExpr ::= MultiplicativeExpr (AdditiveOp MultiplicativeExpr)* AdditiveOp ::= '+' | '-' MultiplicativeExpr ::= UnionExpr ('*' UnionExpr)* UnionExpr ::= PathExpr ("|" PathExpr)* Literal ::= '"' /[^"]* / '"' | "'" /[^']* / "'" Number ::= /[0-9]+/ /* Names can contain whitespace in the interior */ NameNoWS ::= [^][|/\= \t\n] | \\. NameWS ::= [^][|/\=] | \\. Name ::= NameNoWS NameWS* NameNoWS | NameNoWS VariableReference ::= '$' /[a-zA-Z_][a-zA-Z0-9_]*/ Additional stuff ================ Just for reference, not really interesting as documentation XPath 1.0 (from http://www.w3.org/TR/xpath) ------------------------------------------- [ 1] LocationPath ::= RelativeLocationPath | AbsoluteLocationPath [ 2] AbsoluteLocationPath ::= '/' RelativeLocationPath? | AbbreviatedAbsoluteLocationPath [ 3] RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | AbbreviatedRelativeLocationPath [ 4] Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep [ 5] AxisSpecifier ::= AxisName '::' | AbbreviatedAxisSpecifier [ 6] AxisName ::= 'ancestor' | 'ancestor-or-self' | 'attribute' | 'child' | 'descendant' | 'descendant-or-self' | 'following' | 'following-sibling' | 'namespace' | 'parent' | 'preceding' | 'preceding-sibling' | 'self' [ 7] NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' [ 8] Predicate ::= '[' PredicateExpr ']' [ 9] PredicateExpr ::= Expr [10] AbbreviatedAbsoluteLocationPath ::= '//' RelativeLocationPath [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step [12] AbbreviatedStep ::= '.' | '..' [13] AbbreviatedAxisSpecifier ::= '@'? [14] Expr ::= OrExpr [15] PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument )* )? ')' [17] Argument ::= Expr [18] UnionExpr ::= PathExpr | UnionExpr '|' PathExpr [19] PathExpr ::= LocationPath | FilterExpr | FilterExpr '/' RelativeLocationPath | FilterExpr '//' RelativeLocationPath [20] FilterExpr ::= PrimaryExpr | FilterExpr Predicate [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 [25] AdditiveExpr ::= MultiplicativeExpr | AdditiveExpr '+' MultiplicativeExpr | AdditiveExpr '-' MultiplicativeExpr [26] MultiplicativeExpr ::= UnaryExpr | MultiplicativeExpr MultiplyOperator UnaryExpr | MultiplicativeExpr 'div' UnaryExpr | MultiplicativeExpr 'mod' UnaryExpr [27] UnaryExpr ::= UnionExpr | '-' UnaryExpr [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 ::= (#x20 | #x9 | #xD | #xA)+ Useful subset ------------- Big swath of XPath 1.0 that might be interesting for Augeas start symbol [14] Expr [14] Expr ::= OrExpr [21] OrExpr ::= AndExpr ('or' AndExpr)* [22] AndExpr ::= EqualityExpr ('and' EqualityExpr)* [23] EqualityExpr ::= RelationalExpr | EqualityExpr '=' RelationalExpr | EqualityExpr '!=' RelationalExpr [24] RelationalExpr ::= AdditiveExpr | RelationalExpr '<' AdditiveExpr | RelationalExpr '>' AdditiveExpr | RelationalExpr '<=' AdditiveExpr | RelationalExpr '>=' AdditiveExpr [25] AdditiveExpr ::= MultiplicativeExpr | AdditiveExpr '+' MultiplicativeExpr | AdditiveExpr '-' MultiplicativeExpr [26] MultiplicativeExpr ::= UnaryExpr | MultiplicativeExpr MultiplyOperator UnaryExpr [27] UnaryExpr ::= UnionExpr | '-' UnaryExpr [18] UnionExpr ::= PathExpr ('|' PathExpr)* [19] PathExpr ::= LocationPath | FilterExpr | FilterExpr '/' RelativeLocationPath | FilterExpr '//' RelativeLocationPath [ 1] LocationPath ::= RelativeLocationPath | AbsoluteLocationPath [ 3] RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | AbbreviatedRelativeLocationPath [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step [ 2] AbsoluteLocationPath ::= '/' RelativeLocationPath? | AbbreviatedAbsoluteLocationPath [10] AbbreviatedAbsoluteLocationPath ::= '//' RelativeLocationPath [ 4] Step ::= AxisSpecifier NameTest Predicate* | '.' | '..' [ 5] AxisSpecifier ::= AxisName '::' | <epsilon> [ 6] AxisName ::= 'ancestor' | 'ancestor-or-self' | 'attribute' | 'child' | 'descendant' | 'descendant-or-self' | 'following' | 'following-sibling' | 'namespace' | 'parent' | 'preceding' | 'preceding-sibling' | 'self' [ 8] Predicate ::= '[' Expr ']' [20] FilterExpr ::= PrimaryExpr Predicate* [15] PrimaryExpr ::= '(' Expr ')' | Literal | Number | FunctionCall [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument )* )? ')' [17] Argument ::= Expr Lexical structure [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 ::= '*' | QName [38] NodeType ::= 'comment' | 'text' | 'processing-instruction' | 'node' [39] ExprWhitespace ::= (#x20 | #x9 | #xD | #xA)+
Generated by dwww version 1.14 on Sun Feb 2 13:33:25 CET 2025.