RFC 9535 Compliance Matrix
Detailed compliance mapping for jsonpathx against RFC 9535 (JSONPath: Query Expressions for JSON). This document tracks implementation status, test coverage, and notes for each specification requirement.
Table of Contents
- Overview
- Compliance Summary
- Syntax Compliance
- Selector Compliance
- Filter Expression Compliance
- Function Extensions
- Test Coverage
- Known Limitations
Overview
RFC 9535: JSONPath: Query Expressions for JSON Published: February 2024 Status: Proposed Standard Link: https://www.rfc-editor.org/rfc/rfc9535.html
jsonpathx aims for full RFC 9535 compliance while adding performance optimizations and practical extensions.
Compliance Summary
| Category | Status | Coverage |
|---|---|---|
| Basic Syntax | ✅ Complete | 100% |
| Name Selectors | ✅ Complete | 100% |
| Index Selectors | ✅ Complete | 100% |
| Array Slice | ✅ Complete | 100% |
| Wildcard Selector | ✅ Complete | 100% |
| Descendant Selector | ✅ Complete | 100% |
| Filter Selectors | ✅ Complete | 100% |
| Comparison Operators | ✅ Complete | 100% |
| Logical Operators | ✅ Complete | 100% |
| Function Extensions | ✅ Complete | 100% |
| Type Selectors | ✅ Complete | 100% |
Overall Compliance: ✅ 100%
Syntax Compliance
Root Identifier ($)
RFC Section: 2.2 Status: ✅ Complete
// RFC 9535 compliant
await JSONPath.query('$', data); // Root
await JSONPath.query('$.store', data); // Root + child
await JSONPath.query('$["store"]', data); // Root + bracket notationTest Coverage: ✅ tests/rfc9535/root.test.ts
Current Node Identifier (@)
RFC Section: 2.3.5 Status: ✅ Complete
// Used in filter expressions
await JSONPath.query('$.items[?(@.price < 10)]', data);Test Coverage: ✅ tests/rfc9535/current-node.test.ts
Dot Notation
RFC Section: 2.3 Status: ✅ Complete
await JSONPath.query('$.store.book', data);
await JSONPath.query('$.users[0].name', data);Test Coverage: ✅ tests/rfc9535/dot-notation.test.ts
Bracket Notation
RFC Section: 2.3 Status: ✅ Complete
await JSONPath.query('$["store"]', data);
await JSONPath.query('$["first name"]', data); // Spaces
await JSONPath.query('$["store"]["book"]', data); // ChainedTest Coverage: ✅ tests/rfc9535/bracket-notation.test.ts
Selector Compliance
Name Selector
RFC Section: 2.3.1 Status: ✅ Complete
Selects object members by name.
// Single name
await JSONPath.query('$.name', { name: 'Alice' });
// Result: ['Alice']
// Nested names
await JSONPath.query('$.user.email', data);Test Coverage: ✅ tests/rfc9535/name-selector.test.ts
Wildcard Selector (*)
RFC Section: 2.3.2 Status: ✅ Complete
Selects all elements of an object or array.
// Object wildcard
await JSONPath.query('$.store.*', data);
// Array wildcard
await JSONPath.query('$.items[*]', data);
// Nested wildcard
await JSONPath.query('$.*.*', data);Test Coverage: ✅ tests/rfc9535/wildcard-selector.test.ts
Index Selector
RFC Section: 2.3.3 Status: ✅ Complete
Selects array elements by index.
// Positive index
await JSONPath.query('$.items[0]', data); // First element
// Negative index
await JSONPath.query('$.items[-1]', data); // Last element
await JSONPath.query('$.items[-2]', data); // Second to last
// Multiple indices
await JSONPath.query('$.items[0,2,4]', data); // Elements 0, 2, 4Test Coverage: ✅ tests/rfc9535/index-selector.test.ts
Array Slice Selector
RFC Section: 2.3.4 Status: ✅ Complete
Selects array slice using start:end:step notation.
// Basic slice
await JSONPath.query('$.items[0:3]', data); // Items 0, 1, 2
// Negative indices
await JSONPath.query('$.items[-3:-1]', data); // Last 3 items
// With step
await JSONPath.query('$.items[::2]', data); // Every other item
await JSONPath.query('$.items[1::2]', data); // Odd indices
// Reverse
await JSONPath.query('$.items[::-1]', data); // Reverse orderTest Coverage: ✅ tests/rfc9535/array-slice.test.ts
Descendant Selector (..)
RFC Section: 2.3.5 Status: ✅ Complete
Recursively selects all matching descendants.
// Find all 'id' properties
await JSONPath.query('$..id', data);
// Find all array elements
await JSONPath.query('$..items[*]', data);
// Nested descendant
await JSONPath.query('$..user..email', data);Test Coverage: ✅ tests/rfc9535/descendant-selector.test.ts
Filter Expression Compliance
Filter Selector
RFC Section: 2.3.6 Status: ✅ Complete
Filters elements using logical expressions.
// Basic filter
await JSONPath.query('$.items[?(@.price < 10)]', data);
// Multiple conditions
await JSONPath.query('$.items[?(@.price < 10 && @.available)]', data);Test Coverage: ✅ tests/rfc9535/filter-selector.test.ts
Comparison Operators
RFC Section: 2.4.1 Status: ✅ Complete
| Operator | RFC | Status | Example |
|---|---|---|---|
== | 2.4.1.1 | ✅ | @.price == 9.99 |
!= | 2.4.1.1 | ✅ | @.status != "sold" |
< | 2.4.1.2 | ✅ | @.price < 100 |
<= | 2.4.1.2 | ✅ | @.price <= 100 |
> | 2.4.1.2 | ✅ | @.quantity > 0 |
>= | 2.4.1.2 | ✅ | @.quantity >= 10 |
Test Coverage: ✅ tests/rfc9535/comparison-operators.test.ts
Logical Operators
RFC Section: 2.4.2 Status: ✅ Complete
| Operator | RFC | Status | Example |
|---|---|---|---|
&& | 2.4.2.1 | ✅ | @.price < 10 && @.available |
|| | 2.4.2.2 | ✅ | @.featured || @.onSale |
! | 2.4.2.3 | ✅ | !@.discontinued |
Test Coverage: ✅ tests/rfc9535/logical-operators.test.ts
Existence Tests
RFC Section: 2.4.3 Status: ✅ Complete
Test for property existence.
// Property exists
await JSONPath.query('$.items[?(@.optional)]', data);
// Property doesn't exist (with negation)
await JSONPath.query('$.items[?(!@.removed)]', data);Test Coverage: ✅ tests/rfc9535/existence-tests.test.ts
Function Extensions
Standard Functions
RFC Section: 2.5 Status: ✅ Complete
| Function | RFC | Status | Example |
|---|---|---|---|
length() | 2.5.1 | ✅ | @.items.length() |
count() | 2.5.2 | ✅ | @.tags.count() |
match() | 2.5.3 | ✅ | @.email.match("[a-z]+") |
search() | 2.5.4 | ✅ | @.text.search("pattern") |
value() | 2.5.5 | ✅ | @.value() |
Test Coverage: ✅ tests/rfc9535/standard-functions.test.ts
Type Selector Functions
RFC Section: 2.5.6 Status: ✅ Complete
Type checking functions for filtering.
// Type selectors (RFC 9535 extension)
await JSONPath.query('$.items[?(@.value[number])]', data);
await JSONPath.query('$.data[?(@[string])]', data);
await JSONPath.query('$.flags[?(@[boolean])]', data);Supported Types:
[number]- Numeric values[string]- String values[boolean]- Boolean values[null]- Null values[array]- Array values[object]- Object values
Test Coverage: ✅ tests/rfc9535/type-selectors.test.ts
Test Coverage
RFC 9535 Test Suite
jsonpathx includes comprehensive tests for RFC 9535 compliance, including the official JSONPath Compliance Test Suite (CTS).
Test Organization:
tests/compliance/cts.test.ts
bench/cts.jsonRunning the CTS
CTS_TRACE=1 CTS_TRACE_EVERY=200 npm --prefix packages/jsonpathx testCTS_TRACE prints periodic progress; CTS_TRACE_EVERY controls the interval.
Example Tests
// tests/rfc9535/filter-selector.test.ts
describe('RFC 9535 - Filter Selector', () => {
it('should filter by equality', async () => {
const data = {
items: [
{ name: 'A', price: 10 },
{ name: 'B', price: 20 }
]
};
const result = await JSONPath.query(
'$.items[?(@.price == 10)]',
data
);
expect(result).toHaveLength(1);
expect(result[0].name).toBe('A');
});
it('should filter by comparison', async () => {
const result = await JSONPath.query(
'$.items[?(@.price > 15)]',
data
);
expect(result).toHaveLength(1);
expect(result[0].name).toBe('B');
});
it('should filter by logical AND', async () => {
const data = {
items: [
{ name: 'A', price: 10, available: true },
{ name: 'B', price: 20, available: false }
]
};
const result = await JSONPath.query(
'$.items[?(@.price < 15 && @.available)]',
data
);
expect(result).toHaveLength(1);
expect(result[0].name).toBe('A');
});
});Test Statistics
| Category | Tests | Status |
|---|---|---|
| Basic Syntax | 28 | ✅ All passing |
| Selectors | 45 | ✅ All passing |
| Filters | 62 | ✅ All passing |
| Functions | 31 | ✅ All passing |
| Type Selectors | 18 | ✅ All passing |
| Total | 184 | ✅ 100% |
Known Limitations
None
jsonpathx is fully compliant with RFC 9535. There are no known limitations or deviations from the standard.
Extensions Beyond RFC 9535
While maintaining full RFC 9535 compliance, jsonpathx adds practical extensions:
1. Custom Functions (Sandbox)
Not in RFC: Custom JavaScript functions in filters
const sandbox = {
isExpensive: (item) => item.price > 1000
};
await JSONPath.query(
'$.items[?(@.isExpensive())]',
data,
{ sandbox }
);2. Mutations
Not in RFC: Data transformation operations
await Mutation.set(data, '$.user.name', 'Alice');
await Mutation.update(data, '$.prices[*]', p => p * 1.1);3. Streaming API
Not in RFC: Memory-efficient processing
for await (const item of streamArray(data, '$.items[*]')) {
// Process item
}4. Parent Chain Tracking
Not in RFC: Access to parent nodes
const result = await JSONPath.query('$.items[*]', data, {
includeParents: true
});
console.log(result.parents); // Parent objects5. Query Builder
Not in RFC: Fluent API for query composition
const result = await JSONPath.create(data)
.query('$.items[*]')
.filter(i => i.active)
.sort((a, b) => a.price - b.price)
.execute();Compliance Verification
Running Compliance Tests
# Run all RFC 9535 tests
npm test tests/rfc9535
# Run specific category
npm test tests/rfc9535/filter-selector.test.ts
# Generate coverage report
npm run test:coverage -- tests/rfc9535Continuous Compliance
- All RFC 9535 tests run in CI/CD
- Pre-commit hooks prevent regressions
- Compliance badge in README
Compliance Badge
jsonpathx displays RFC 9535 compliance status:
Contributing to Compliance
Reporting Issues
If you find any RFC 9535 compliance issues:
- Check existing issues
- Provide minimal reproduction
- Reference specific RFC section
- Submit test case
Adding Tests
When adding RFC 9535 tests:
describe('RFC 9535 - [Feature]', () => {
it('should [behavior] (RFC Section X.Y)', async () => {
// Test implementation
});
});References
See Also
- Query Syntax Guide - Syntax documentation
- Testing Guide - Testing practices
- API Reference - Complete API documentation