Managing JSON-path filter queries for oneM2M contentFilterQuery filterCriteria.
Implements the 'JSON-path' contentFilterSyntax for oneM2M contentFilterQuery filterCriteria, as specified in Annex J.2 of TS-0001 ("Syntaxes for content based discovery of <contentInstance>").
The following syntax rules are supported:
- '$' refers to the entire target data.
- '[n]' refers to the n-th member of a JSON array.
- '.name' (dot operator followed by a name) refers to a member of a JSON object.
- A name MUST be quoted with "'" (single quote) when it contains any of: '$', '.', ' ' (space), '[', ']', '{', '}'.
- A single space character must separate a reserved keyword from the surrounding query string components.
- Reserved keywords: EQ, NE, GT, LT, GE, LE, MATCH, AND, OR.
The following assumptions are made in the implementation, since the spec does not provide a complete grammar or examples:
- AND and OR are evaluated strictly left-to-right, with no precedence between them.
- MATCH is implemented as a case-SENSITIVE substring test.
- The query is evaluated once per <contentInstance> (CIN) resource.
- The implicit root '$' of the path expression is always the CIN's parsed 'con' attribute value (not some larger document).
- The overall result of evaluating a filterCriteria query against one CIN is a boolean: match (include the CIN in the result set) or no match.
- If a path expression does not resolve (missing object member, array index out of range,
- indexing into a scalar, etc.), the clause evaluates to "no match" (False) rather than raising an error, for every keyword. This makes filterCriteria evaluation robust against heterogeneous CON payloads.
- GT/LT/GE/LE require BOTH the resolved value and the literal to be numbers (int or float);
- a type mismatch evaluates to False rather than raising, consistent with A5's "be permissive, don't except" stance. EQ/NE compare equal types only (a number is never == to its string representation); MATCH requires the resolved value to be a string.
- Literal values (the right-hand side of a clause) are delimited asfollows:
- A STRING literal is surrounded by DOUBLE quotes ("..."), and is escaped exactly like a JSON string. Decoding is delegated to json.loads so the escaping behaviour is JSON's by construction.
- A NUMBER literal is a bare, unquoted token parsed as int then float (e.g. 21, 21.5).
- Examples of valid filterCriteria queries:
- $.temperature EQ 21
- $.temperature GT 21 AND $.humidity LT 50
- $.sensor.values[2] MATCH "abc"
- $.sensor.'a.b'[0] NE 42 OR $.sensor.'a b' EQ "hello world"
| Class | |
A single clause in a filterCriteria query: a path expression, a comparison keyword, and a literal value. |
| Class | |
A parsed filterCriteria query: a flat sequence of clauses joined by AND / OR combinators (one fewer combinator than there are clauses). |
| Class | |
The reserved keywords of the J.2 query syntax. |
| Class | |
A single step in a path expression: either a member-name access or an array index access. |
| Class | |
Kind of a single step in a path expression. |
| Class | |
A single token produced by the tokenizer. |
| Class | |
Lexical category of a token produced by the tokenizer. |
| Exception | |
Raised when a filterCriteria query string cannot be parsed. |
| Function | evaluate |
Evaluates a single clause against rootValue (the parsed CON value). |
| Function | evaluate |
Evaluates a fully parsed FilterExpression against conValue (the parsed JSON value of a CIN's 'con' attribute), returning True if the CIN should be included in the result set. |
| Function | matches |
One-shot convenience function: parses query (a filterCriteria string) and evaluates it against conValue (the already-JSON-parsed value of a CIN's 'con' attribute), returning True if the CIN matches and should be included in the result set. |
| Function | parse |
Parses a full filterCriteria query string into a FilterExpression object. |
| Function | parse |
Parses a oneM2M-style path expression (e.g. "$.sensor.values[2]" or "$.'a.b'[0]") into a list of PathStep objects. |
| Function | resolve |
Resolves a parsed path expression against rootValue (the CIN's already-JSON-parsed 'con' attribute). Returns the resolved value, or the _ABSENT sentinel if any step cannot be applied. |
| Function | tokenize |
Tokenizes a full filterCriteria query string of the form: pathExpr KEYWORD literal (AND|OR pathExpr KEYWORD literal)*` |
| Constant | COMBINATOR |
The set of keywords that are used to combine clauses in a filterCriteria query. |
| Constant | COMBINATOR |
If True, AND binds more tightly than OR in filterCriteria evaluation. |
| Constant | COMPARISON |
The set of keywords that are used for comparison in a single clause of a filterCriteria query. |
| Function | _is |
Returns True if the value is an int or float (but not bool), False otherwise. |
| Function | _parse |
Parses a literal's raw text into a Python value. |
| Function | _split |
Splits the raw query string into whitespace-delimited components, while keeping quoted spans intact. |
| Function | _unquote |
Strips a single layer of surrounding single quotes, if present. |
| Constant | _ABSENT |
Internal sentinel. A path did not resolve to any value. |
| Constant | _SPECIAL |
The set of characters that force quoting of a name or literal per the spec rule. |
Evaluates a single clause against rootValue (the parsed CON value).
| Parameters | |
clause:Clause | The Clause object to evaluate. |
rootAny | The root value to resolve the path against (the parsed 'con' attribute of a <contentInstance>). |
| Returns | |
bool | True if the clause matches, False otherwise. |
| Raises | |
FilterQuerySyntaxError | If the clause's keyword is unknown. |
Evaluates a fully parsed FilterExpression against conValue (the parsed JSON value of a CIN's 'con' attribute), returning True if the CIN should be included in the result set.
| Parameters | |
expr:FilterExpression | The FilterExpression object to evaluate. |
conAny | The parsed JSON value of the CIN's 'con' attribute. |
| Returns | |
bool | True if the CIN matches the filter expression, False otherwise. |
One-shot convenience function: parses query (a filterCriteria string) and evaluates it against conValue (the already-JSON-parsed value of a CIN's 'con' attribute), returning True if the CIN matches and should be included in the result set.
For repeated evaluation of the same query against many CIN resources, call
parseFilterQuery () once and reuse the FilterExpression with evaluateFilterExpression ()
to avoid re-parsing on every resource.
Raises:
| Parameters | |
query:str | The raw filterCriteria query string. |
conAny | The parsed JSON value of the CIN's 'con' attribute. |
| Returns | |
bool | True if the CIN matches the filter query, False otherwise. |
Parses a full filterCriteria query string into a FilterExpression object.
| Parameters | |
query:str | The raw filterCriteria query string. |
| Returns | |
FilterExpression | A FilterExpression object representing the parsed query. |
| Raises | |
FilterQuerySyntaxError | If the query string is malformed. |
Parses a oneM2M-style path expression (e.g. "$.sensor.values[2]" or "$.'a.b'[0]") into a list of PathStep objects.
Grammar (per the spec's stated rules):
pathExpr := '$' step*step := '.' name | '[' index ']'name := plainName | "'" quotedName "'"
- plainName is read up to the next '.' or '[' (whichever comes first);
- quotedName runs until the matching closing quote and may contain any character, including '.', '[', ']', '{', '}', and spaces.
| Parameters | |
pathstr | The raw path expression string. |
| Returns | |
list[ | A list of PathStep objects representing the steps in the path expression. |
| Raises | |
FilterQuerySyntaxError | If the path expression is malformed. |
Resolves a parsed path expression against rootValue (the CIN's already-JSON-parsed 'con' attribute).
Returns the resolved value, or the _ABSENT sentinel if any step cannot be applied.
| Parameters | |
rootAny | The root value to resolve the path against (the parsed 'con' attribute of a <contentInstance>). |
steps:list[ | The list of PathStep objects representing the parsed path expression. |
| Returns | |
Any |
|
Tokenizes a full filterCriteria query string of the form: pathExpr KEYWORD literal (AND|OR pathExpr KEYWORD literal)*`
into a flat list of Token objects.
| Parameters | |
query:str | The raw filterCriteria query string. |
| Returns | |
list[ | A list of Token objects representing the components of the query string. |
The set of keywords that are used to combine clauses in a filterCriteria query.
| Value |
|
The set of keywords that are used for comparison in a single clause of a filterCriteria query.
| Value |
|
Returns True if the value is an int or float (but not bool), False otherwise.
| Parameters | |
value:Any | The value to check. |
| Returns | |
bool | True if the value is an int or float (but not bool), False otherwise. |
Parses a literal's raw text into a Python value.
| Parameters | |
rawstr | The raw token text, possibly surrounded by double quotes. |
| Returns | |
The parsed Python value | str, int, float, or the raw token text if it cannot be parsed. |
| Raises | |
FilterQuerySyntaxError | If the token is a malformed double-quoted string literal. |
Splits the raw query string into whitespace-delimited components, while keeping quoted spans intact.
Two independent quote contexts are recognised:
- single-quoted spans ('...') protect spaces inside path member NAMES;
- double-quoted spans ("...") protect spaces inside string VALUE literals, using JSON escaping, so a backslash escapes the following character and an escaped '"' does not close the span.
A space outside of any quoted span is a component separator. An
unterminated span of either kind raises FilterQuerySyntaxError.
| Parameters | |
query:str | The raw filterCriteria query string. |
| Returns | |
list[ | A list of raw components (tokens) of the query string, with quotes preserved. |
| Raises | |
FilterQuerySyntaxError | If a quoted span is unterminated. |
Strips a single layer of surrounding single quotes, if present.
Used for path member NAMES (single-quoted per the spec). String VALUE
literals use double quotes and are handled by _parseLiteralValue via
json.loads, not here.
| Parameters | |
rawstr | The raw token text, possibly surrounded by single quotes. |
| Returns | |
str | The token text with surrounding single quotes removed, if they were present. |