0
# Value Manipulation
1
2
Functions for getting, setting, and transforming values at specific JSONPath locations. Includes support for creating intermediate objects (vivification) and applying transformations to multiple matching elements in place.
3
4
## Capabilities
5
6
### Value Function
7
8
Get or set the value of the first element matching a JSONPath expression. When setting values, it creates intermediate objects as needed.
9
10
```javascript { .api }
11
/**
12
* Get or set value of first matching element
13
* @param {Object} obj - Target object (must be an object)
14
* @param {string|Array} pathExpression - JSONPath expression string or normalized path array
15
* @param {*} [newValue] - New value to set (optional, creates intermediate objects/arrays as needed)
16
* @returns {*} Current value (if getting) or new value (if setting)
17
*/
18
function value(obj, pathExpression, newValue);
19
```
20
21
**Usage Examples:**
22
23
```javascript
24
const jp = require('jsonpath');
25
26
const data = {
27
store: {
28
book: [
29
{ author: "Nigel Rees", price: 8.95 },
30
{ author: "Evelyn Waugh", price: 12.99 }
31
]
32
}
33
};
34
35
// Get first matching value
36
const firstAuthor = jp.value(data, '$..author');
37
// Result: "Nigel Rees"
38
39
const firstPrice = jp.value(data, '$..price');
40
// Result: 8.95
41
42
// Set existing value
43
jp.value(data, '$..price', 9.99);
44
console.log(data.store.book[0].price); // 9.99
45
46
// Create new properties (vivification)
47
const emptyObj = {};
48
jp.value(emptyObj, '$.store.name', 'My Bookstore');
49
console.log(emptyObj); // { store: { name: 'My Bookstore' } }
50
51
// Create array elements
52
jp.value(emptyObj, '$.items[0]', 'first item');
53
jp.value(emptyObj, '$.items[1]', 'second item');
54
console.log(emptyObj.items); // ['first item', 'second item']
55
56
// Set values using complex expressions
57
jp.value(data, '$..book[?(@.author=="Nigel Rees")].price', 10.50);
58
```
59
60
### Parent Function
61
62
Get the parent object of the first element matching a JSONPath expression.
63
64
```javascript { .api }
65
/**
66
* Get parent of first matching element
67
* @param {Object} obj - Target object (must be an object)
68
* @param {string} pathExpression - JSONPath expression string
69
* @returns {*} Parent object of first match
70
*/
71
function parent(obj, pathExpression);
72
```
73
74
**Usage Examples:**
75
76
```javascript
77
const jp = require('jsonpath');
78
79
const data = {
80
store: {
81
book: [
82
{ author: "Nigel Rees", title: "Sayings", price: 8.95 },
83
{ author: "Evelyn Waugh", title: "Sword", price: 12.99 }
84
]
85
}
86
};
87
88
// Get parent of first author
89
const parentOfAuthor = jp.parent(data, '$..author');
90
console.log(parentOfAuthor);
91
// Result: { author: "Nigel Rees", title: "Sayings", price: 8.95 }
92
93
// Get parent of a specific book
94
const parentOfBook = jp.parent(data, '$.store.book[0]');
95
console.log(parentOfBook);
96
// Result: [{ author: "Nigel Rees", ... }, { author: "Evelyn Waugh", ... }]
97
98
// Get parent of specific property
99
const parentOfPrice = jp.parent(data, '$.store.book[1].price');
100
console.log(parentOfPrice);
101
// Result: { author: "Evelyn Waugh", title: "Sword", price: 12.99 }
102
```
103
104
### Apply Function
105
106
Apply a transformation function to all elements matching a JSONPath expression, modifying them in place. Returns the modified nodes.
107
108
```javascript { .api }
109
/**
110
* Apply function to all matching elements, modifying them in place
111
* @param {Object} obj - Target object (must be an object)
112
* @param {string} pathExpression - JSONPath expression string
113
* @param {Function} fn - Transformation function: (value) => newValue
114
* @returns {Array<Object>} Array of modified node objects with {path: Array, value: any}
115
*/
116
function apply(obj, pathExpression, fn);
117
```
118
119
**Usage Examples:**
120
121
```javascript
122
const jp = require('jsonpath');
123
124
const data = {
125
store: {
126
book: [
127
{ author: "nigel rees", price: 8.95 },
128
{ author: "evelyn waugh", price: 12.99 }
129
]
130
}
131
};
132
133
// Transform all author names to uppercase
134
const modifiedNodes = jp.apply(data, '$..author', function(value) {
135
return value.toUpperCase();
136
});
137
138
console.log(modifiedNodes);
139
// Result: [
140
// { path: ['$', 'store', 'book', 0, 'author'], value: 'NIGEL REES' },
141
// { path: ['$', 'store', 'book', 1, 'author'], value: 'EVELYN WAUGH' }
142
// ]
143
144
console.log(data.store.book[0].author); // "NIGEL REES" (modified in place)
145
146
// Apply price discount to all books
147
jp.apply(data, '$..price', function(price) {
148
return price * 0.9; // 10% discount
149
});
150
151
// Transform arrays (e.g., reverse order)
152
const arrayData = { numbers: [1, 2, 3], letters: ['a', 'b', 'c'] };
153
jp.apply(arrayData, '$..*[?(@.length > 1)]', function(array) {
154
return array.reverse();
155
});
156
console.log(arrayData.numbers); // [3, 2, 1]
157
158
// Complex transformations using context
159
jp.apply(data, '$..book[*]', function(book) {
160
return {
161
...book,
162
slug: book.author.toLowerCase().replace(/\s+/g, '-'),
163
discountedPrice: book.price * 0.8
164
};
165
});
166
```
167
168
## Advanced Features
169
170
### Vivification (Auto-creation)
171
172
The `value` function automatically creates intermediate objects and arrays when setting values on non-existent paths:
173
174
```javascript
175
const jp = require('jsonpath');
176
177
const obj = {};
178
179
// Creates nested object structure
180
jp.value(obj, '$.user.profile.name', 'John');
181
console.log(obj);
182
// Result: { user: { profile: { name: 'John' } } }
183
184
// Creates array with specific index
185
jp.value(obj, '$.user.hobbies[0]', 'reading');
186
jp.value(obj, '$.user.hobbies[2]', 'hiking');
187
console.log(obj.user.hobbies);
188
// Result: ['reading', undefined, 'hiking']
189
190
// Mixed structures
191
jp.value(obj, '$.data.items[0].tags[1]', 'important');
192
console.log(obj.data.items);
193
// Result: [{ tags: [undefined, 'important'] }]
194
```
195
196
### Transformation Ordering
197
198
The `apply` function processes matches from bottom-up (deepest paths first) to handle structural changes safely:
199
200
```javascript
201
const jp = require('jsonpath');
202
203
const data = { a: { b: [1, { c: [2, 3] }] } };
204
205
// This works safely even though it modifies structure
206
jp.apply(data, '$..*[?(@.length > 1)]', function(array) {
207
return array.reverse();
208
});
209
210
console.log(data);
211
// Result: { a: { b: [{ c: [3, 2] }, 1] } }
212
```
213
214
## Error Handling
215
216
All manipulation functions validate their inputs:
217
218
- Throws `AssertionError` if `obj` is not an object
219
- Throws `AssertionError` if `pathExpression` is not valid
220
- Throws `AssertionError` if `fn` is not a function (for `apply`)
221
- `parent` throws error if no matches found
222
- `value` returns `undefined` if getting non-existent path
223
- `apply` returns empty array if no matches found