WARNING: This document is a work in progress, just like JSONSelect itself. View or contribute to the latest version on github
- introduction
- levels
- language overview
- grouping
- selectors
- pseudo classes
- expressions
- combinators
- grammar
- conformance tests
- references
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.
| pattern | meaning | level |
|---|---|---|
| * | Any node | 1 |
| 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 |
(Adapted from CSS3 and json.org)
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]
;
See https://github.com/lloyd/JSONSelectTests
In no particular order.
- http://json.org/
- http://www.w3.org/TR/css3-selectors/
- http://ejohn.org/blog/selectors-that-people-actually-use/
- [http://shauninman.com/archive/2008/05/05/css_qualified_selectors]( * http://shauninman.com/archive/2008/05/05/css_qualified_selectors)
- http://snook.ca/archives/html_and_css/css-parent-selectors
- http://remysharp.com/2010/10/11/css-parent-selector/
- https://github.com/jquery/sizzle/wiki/Sizzle-Home