WARNING: This document is a work in progress, just like JSONSelect itself. View or contribute to the latest version on github
- language overview
- pseudo classes
- conformance tests
JSONSelect defines a language very similar in syntax and structure to CSS3 Selectors. JSONSelect expressions are patterns which can be matched against JSON documents.
Potential applications of JSONSelect include:
- Simplified programmatic matching of nodes within JSON documents.
- Stream filtering, allowing efficient and incremental matching of documents.
- As a query language for a document database.
The specification of JSONSelect is broken into three levels. Higher levels include more powerful constructs, and are likewise more complicated to implement and use.
JSONSelect Level 1 is a small subset of CSS3. Every feature is derived from a CSS construct that directly maps to JSON. A level 1 implementation is not particularly complicated while providing basic querying features.
JSONSelect Level 2 builds upon Level 1 adapting more complex CSS constructs which allow expressions to include constraints such as patterns that match against values, and those which consider a node's siblings. Level 2 is still a direct adaptation of CSS, but includes constructs whose semantic meaning is significantly changed.
JSONSelect Level 3 adds constructs which do not necessarily have a direct analog in CSS, and are added to increase the power and convenience of the selector language. These include aliases, wholly new pseudo class functions, and more blue sky dreaming.
|T||A node of type T, where T is one string, number, object, array, boolean, or null||1|
|T.key||A node of type T which is the child of an object and is the value its parents key property||1|
|T."complex key"||Same as previous, but with property name specified as a JSON string||1|
|T:root||A node of type T which is the root of the JSON document||1|
|T:nth-child(n)||A node of type T which is the nth child of an array parent||1|
|T:nth-last-child(n)||A node of type T which is the nth child of an array parent counting from the end||2|
|T:first-child||A node of type T which is the first child of an array parent (equivalent to T:nth-child(1)||1|
|T:last-child||A node of type T which is the last child of an array parent (equivalent to T:nth-last-child(1)||2|
|T:only-child||A node of type T which is the only child of an array parent||2|
|T:empty||A node of type T which is an array or object with no child||2|
|T U||A node of type U with an ancestor of type T||1|
|T > U||A node of type U with a parent of type T||1|
|T ~ U||A node of type U with a sibling of type T||2|
|S1, S2||Any node which matches either selector S1 or S2||1|
|T:has(S)||A node of type T which has a child node satisfying the selector S||3|
|T:expr(E)||A node of type T with a value that satisfies the expression E||3|
|T:val(V)||A node of type T with a value that is equal to V||3|
|T:contains(S)||A node of type T with a string value contains the substring S||3|
selectors_group : selector [ `,` selector ]* ; selector : simple_selector_sequence [ combinator simple_selector_sequence ]* ; combinator : `>` | \s+ ; simple_selector_sequence /* why allow multiple HASH entities in the grammar? */ : [ type_selector | universal ] [ class | pseudo ]* | [ class | pseudo ]+ ; type_selector : `object` | `array` | `number` | `string` | `boolean` | `null` ; universal : '*' ; class : `.` name | `.` json_string ; pseudo /* Note that pseudo-elements are restricted to one per selector and */ /* occur only in the last simple_selector_sequence. */ : `:` pseudo_class_name | `:` nth_function_name `(` nth_expression `)` | `:has` `(` selectors_group `)` | `:expr` `(` expr `)` | `:contains` `(` json_string `)` | `:val` `(` val `)` ; pseudo_class_name : `root` | `first-child` | `last-child` | `only-child` nth_function_name : `nth-child` | `nth-last-child` nth_expression /* expression is and of the form "an+b" */ : TODO ; expr : expr binop expr | '(' expr ')' | val ; binop : '*' | '/' | '%' | '+' | '-' | '<=' | '>=' | '$=' | '^=' | '*=' | '>' | '<' | '=' | '!=' | '&&' | '||' ; val : json_number | json_string | 'true' | 'false' | 'null' | 'x' ; json_string : `"` json_chars* `"` ; json_chars : any-Unicode-character-except-"-or-\-or-control-character | `\"` | `\\` | `\/` | `\b` | `\f` | `\n` | `\r` | `\t` | \u four-hex-digits ; name : nmstart nmchar* ; nmstart : escape | [_a-zA-Z] | nonascii ; nmchar : [_a-zA-Z0-9-] | escape | nonascii ; escape : \\[^\r\n\f0-9a-fA-F] ; nonascii : [^\0-0177] ;
In no particular order.