File size: 7,538 Bytes
4cadbaf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
**WARNING**: This document is a work in progress, just like JSONSelect itself.
View or contribute to the latest version [on github](http://github.com/lloyd/JSONSelect/blob/master/JSONSelect.md)

# JSONSelect

  1. [introduction](#introduction)
  1. [levels](#levels)
  1. [language overview](#overview)
  1. [grouping](#grouping)
  1. [selectors](#selectors)
  1. [pseudo classes](#pseudo)
  1. [expressions](#expressions)
  1. [combinators](#combinators)
  1. [grammar](#grammar)
  1. [conformance tests](#tests)
  1. [references](#references)

## Introduction<a name="introduction"></a>

JSONSelect defines a language very similar in syntax and structure to
[CSS3 Selectors](http://www.w3.org/TR/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.

## Levels<a name="levels"></a>

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.

## Language Overview<a name="overview"></a>

<table>
<tr><th>pattern</th><th>meaning</th><th>level</th></tr>
<tr><td>*</td><td>Any node</td><td>1</td></tr>
<tr><td>T</td><td>A node of type T, where T is one string, number, object, array, boolean, or null</td><td>1</td></tr>
<tr><td>T.key</td><td>A node of type T which is the child of an object and is the value its parents key property</td><td>1</td></tr>
<tr><td>T."complex key"</td><td>Same as previous, but with property name specified as a JSON string</td><td>1</td></tr>
<tr><td>T:root</td><td>A node of type T which is the root of the JSON document</td><td>1</td></tr>
<tr><td>T:nth-child(n)</td><td>A node of type T which is the nth child of an array parent</td><td>1</td></tr>
<tr><td>T:nth-last-child(n)</td><td>A node of type T which is the nth child of an array parent counting from the end</td><td>2</td></tr>
<tr><td>T:first-child</td><td>A node of type T which is the first child of an array parent (equivalent to T:nth-child(1)</td><td>1</td></tr>
<tr><td>T:last-child</td><td>A node of type T which is the last child of an array parent (equivalent to T:nth-last-child(1)</td><td>2</td></tr>
<tr><td>T:only-child</td><td>A node of type T which is the only child of an array parent</td><td>2</td></tr>
<tr><td>T:empty</td><td>A node of type T which is an array or object with no child</td><td>2</td></tr>
<tr><td>T U</td><td>A node of type U with an ancestor of type T</td><td>1</td></tr>
<tr><td>T > U</td><td>A node of type U with a parent of type T</td><td>1</td></tr>
<tr><td>T ~ U</td><td>A node of type U with a sibling of type T</td><td>2</td></tr>
<tr><td>S1, S2</td><td>Any node which matches either selector S1 or S2</td><td>1</td></tr>
<tr><td>T:has(S)</td><td>A node of type T which has a child node satisfying the selector S</td><td>3</td></tr>
<tr><td>T:expr(E)</td><td>A node of type T with a value that satisfies the expression E</td><td>3</td></tr>
<tr><td>T:val(V)</td><td>A node of type T with a value that is equal to V</td><td>3</td></tr>
<tr><td>T:contains(S)</td><td>A node of type T with a string value contains the substring S</td><td>3</td></tr>
</table>

## Grouping<a name="grouping"></a>

## Selectors<a name="selectors"></a>

## Pseudo Classes<a name="pseudo"></a>

## Expressions<a name="expressions"></a>

## Combinators<a name="combinators"></a>

## Grammar<a name="grammar"></a>

(Adapted from [CSS3](http://www.w3.org/TR/css3-selectors/#descendant-combinators) and
 [json.org](http://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]
      ;

## Conformance Tests<a name="tests"></a>

See [https://github.com/lloyd/JSONSelectTests](https://github.com/lloyd/JSONSelectTests)

## References<a name="references"></a>

In no particular order.

  * [http://json.org/](http://json.org/)
  * [http://www.w3.org/TR/css3-selectors/](http://www.w3.org/TR/css3-selectors/)
  * [http://ejohn.org/blog/selectors-that-people-actually-use/](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://snook.ca/archives/html_and_css/css-parent-selectors)
  * [http://remysharp.com/2010/10/11/css-parent-selector/](http://remysharp.com/2010/10/11/css-parent-selector/)
  * [https://github.com/jquery/sizzle/wiki/Sizzle-Home](https://github.com/jquery/sizzle/wiki/Sizzle-Home)