-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodification.php
More file actions
340 lines (265 loc) · 9.74 KB
/
modification.php
File metadata and controls
340 lines (265 loc) · 9.74 KB
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
<?php
declare(strict_types=1);
require __DIR__ . '/../vendor/autoload.php';
use Kestrel\JsoncParser\JsoncParser;
use Kestrel\JsoncParser\Edit\ModificationOptions;
use Kestrel\JsoncParser\Edit\RemoveMarker;
use Kestrel\JsoncParser\Format\FormattingOptions;
use Kestrel\JsoncParser\Edit\Range;
echo "=== PHP JSONC Parser - Modification & Formatting Examples ===\n\n";
// Example 1: Basic Formatting
echo "1. Formatting JSON\n";
echo str_repeat('-', 50) . "\n";
$unformatted = '{"name":"Alice","age":30,"city":"NYC"}';
echo "Unformatted:\n$unformatted\n\n";
$options = new FormattingOptions(
insertSpaces: true,
tabSize: 2,
insertFinalNewline: false,
eol: "\n"
);
$edits = JsoncParser::format($unformatted, null, $options);
$formatted = JsoncParser::applyEdits($unformatted, $edits);
echo "Formatted:\n$formatted\n\n";
// Example 2: Formatting with Tabs
echo "2. Formatting with Tabs\n";
echo str_repeat('-', 50) . "\n";
$options = new FormattingOptions(
insertSpaces: false, // Use tabs
tabSize: 1,
insertFinalNewline: true
);
$edits = JsoncParser::format($unformatted, null, $options);
$formatted = JsoncParser::applyEdits($unformatted, $edits);
echo "Formatted with tabs:\n$formatted";
// Example 3: Range Formatting
echo "3. Range Formatting (Partial Formatting)\n";
echo str_repeat('-', 50) . "\n";
$json = '{
"section1": {"a": 1,"b": 2},
"section2": {"c":3,"d":4}
}';
echo "Original:\n$json\n\n";
// Format only section2 (find it first)
$section2Start = strpos($json, '"section2"');
$section2End = strrpos($json, '}');
$range = new Range($section2Start, $section2End - $section2Start);
$options = new FormattingOptions(insertSpaces: true, tabSize: 2);
$edits = JsoncParser::format($json, $range, $options);
$formatted = JsoncParser::applyEdits($json, $edits);
echo "After range formatting (only section2):\n$formatted\n\n";
// Example 4: Adding Properties
echo "4. Adding Properties to JSON\n";
echo str_repeat('-', 50) . "\n";
$json = '{"name": "Alice"}';
echo "Original: $json\n\n";
$modOptions = new ModificationOptions(
formattingOptions: new FormattingOptions(insertSpaces: true, tabSize: 2)
);
// Add email
$edits = JsoncParser::modify($json, ['email'], 'alice@example.com', $modOptions);
$json = JsoncParser::applyEdits($json, $edits);
echo "After adding email:\n$json\n\n";
// Add age
$edits = JsoncParser::modify($json, ['age'], 30, $modOptions);
$json = JsoncParser::applyEdits($json, $edits);
echo "After adding age:\n$json\n\n";
// Add nested object
$edits = JsoncParser::modify($json, ['address', 'city'], 'New York', $modOptions);
$json = JsoncParser::applyEdits($json, $edits);
echo "After adding nested address:\n$json\n\n";
// Example 5: Updating Properties
echo "5. Updating Properties\n";
echo str_repeat('-', 50) . "\n";
$json = '{
"name": "Alice",
"age": 30,
"city": "NYC"
}';
echo "Original:\n$json\n\n";
// Update age
$edits = JsoncParser::modify($json, ['age'], 31, $modOptions);
$json = JsoncParser::applyEdits($json, $edits);
echo "After updating age to 31:\n$json\n\n";
// Update with null (JSON null, not deletion)
$edits = JsoncParser::modify($json, ['city'], null, $modOptions);
$json = JsoncParser::applyEdits($json, $edits);
echo "After setting city to null:\n$json\n\n";
// Example 6: Deleting Properties
echo "6. Deleting Properties\n";
echo str_repeat('-', 50) . "\n";
$json = '{
"name": "Alice",
"age": 31,
"city": null,
"temp": "to-delete"
}';
echo "Original:\n$json\n\n";
// Delete a property (use RemoveMarker, not null!)
$edits = JsoncParser::modify($json, ['temp'], RemoveMarker::instance(), $modOptions);
$json = JsoncParser::applyEdits($json, $edits);
echo "After deleting 'temp':\n$json\n\n";
$edits = JsoncParser::modify($json, ['city'], RemoveMarker::instance(), $modOptions);
$json = JsoncParser::applyEdits($json, $edits);
echo "After deleting 'city':\n$json\n\n";
// Example 7: Array Modifications
echo "7. Array Modifications\n";
echo str_repeat('-', 50) . "\n";
$json = '{"items": [1, 2, 3]}';
echo "Original: $json\n\n";
// Replace element at index 1
$edits = JsoncParser::modify($json, ['items', 1], 99, $modOptions);
$json = JsoncParser::applyEdits($json, $edits);
echo "After replacing items[1]:\n$json\n\n";
// Insert at index 0 (using isArrayInsertion)
$insertOptions = new ModificationOptions(
formattingOptions: $modOptions->formattingOptions,
isArrayInsertion: true
);
$edits = JsoncParser::modify($json, ['items', 0], 0, $insertOptions);
$json = JsoncParser::applyEdits($json, $edits);
echo "After inserting at items[0]:\n$json\n\n";
// Append to end (index -1)
$edits = JsoncParser::modify($json, ['items', -1], 100, $modOptions);
$json = JsoncParser::applyEdits($json, $edits);
echo "After appending to end:\n$json\n\n";
// Delete array element
$edits = JsoncParser::modify($json, ['items', 0], RemoveMarker::instance(), $modOptions);
$json = JsoncParser::applyEdits($json, $edits);
echo "After deleting items[0]:\n$json\n\n";
// Example 8: Custom Property Ordering
echo "8. Custom Property Insertion Order\n";
echo str_repeat('-', 50) . "\n";
$json = '{
"zebra": 1,
"apple": 2,
"mango": 3
}';
echo "Original (unsorted):\n$json\n\n";
// Add new property at specific position (alphabetically before "mango")
$customOptions = new ModificationOptions(
formattingOptions: new FormattingOptions(insertSpaces: true, tabSize: 2),
getInsertionIndex: function (array $properties) {
// Insert "banana" in alphabetical order
$properties[] = 'banana';
sort($properties);
return array_search('banana', $properties, true);
}
);
$edits = JsoncParser::modify($json, ['banana'], 4, $customOptions);
$json = JsoncParser::applyEdits($json, $edits);
echo "After adding 'banana' (alphabetically):\n$json\n\n";
// Example 9: Batch Modifications
echo "9. Batch Modifications\n";
echo str_repeat('-', 50) . "\n";
$json = '{}';
echo "Starting with empty object: $json\n\n";
// Apply multiple modifications
$modifications = [
['path' => ['name'], 'value' => 'Configuration'],
['path' => ['version'], 'value' => '1.0.0'],
['path' => ['debug'], 'value' => false],
['path' => ['database', 'host'], 'value' => 'localhost'],
['path' => ['database', 'port'], 'value' => 5432],
];
foreach ($modifications as $mod) {
$edits = JsoncParser::modify($json, $mod['path'], $mod['value'], $modOptions);
$json = JsoncParser::applyEdits($json, $edits);
}
echo "After batch modifications:\n$json\n\n";
// Example 10: Preserving Comments
echo "10. Formatting with Comments Preserved\n";
echo str_repeat('-', 50) . "\n";
$jsonc = '{
// User configuration
"name": "Alice",
/* Email settings */
"email": "alice@example.com"
}';
echo "Original JSONC:\n$jsonc\n\n";
$options = new FormattingOptions(
insertSpaces: true,
tabSize: 4
);
$edits = JsoncParser::format($jsonc, null, $options);
$formatted = JsoncParser::applyEdits($jsonc, $edits);
echo "Formatted (comments preserved):\n$formatted\n\n";
// Example 11: keepLines Option
echo "11. Formatting with keepLines (Minimal Changes)\n";
echo str_repeat('-', 50) . "\n";
$json = '{ "name": "Alice",
"age": 30, "city":
"NYC" }';
echo "Original (irregular spacing):\n$json\n\n";
// Without keepLines (default)
$options = new FormattingOptions(insertSpaces: true, tabSize: 2, keepLines: false);
$edits = JsoncParser::format($json, null, $options);
$formatted1 = JsoncParser::applyEdits($json, $edits);
echo "Formatted without keepLines:\n$formatted1\n\n";
// With keepLines (preserve line structure)
$options = new FormattingOptions(insertSpaces: true, tabSize: 2, keepLines: true);
$edits = JsoncParser::format($json, null, $options);
$formatted2 = JsoncParser::applyEdits($json, $edits);
echo "Formatted with keepLines:\n$formatted2\n\n";
// Example 12: Practical Example - Config File Editor
echo "12. Practical Example - Configuration File Editor\n";
echo str_repeat('-', 50) . "\n";
class ConfigEditor
{
private string $json;
private ModificationOptions $options;
public function __construct(string $json)
{
$this->json = $json;
$this->options = new ModificationOptions(
formattingOptions: new FormattingOptions(
insertSpaces: true,
tabSize: 2,
insertFinalNewline: true
)
);
}
public function set(array $path, mixed $value): self
{
$edits = JsoncParser::modify($this->json, $path, $value, $this->options);
$this->json = JsoncParser::applyEdits($this->json, $edits);
return $this;
}
public function delete(array $path): self
{
$edits = JsoncParser::modify($this->json, $path, RemoveMarker::instance(), $this->options);
$this->json = JsoncParser::applyEdits($this->json, $edits);
return $this;
}
public function get(array $path): mixed
{
$tree = JsoncParser::parseTree($this->json);
$node = JsoncParser::findNodeAtLocation($tree, $path);
return $node ? JsoncParser::getNodeValue($node) : null;
}
public function format(): self
{
$edits = JsoncParser::format($this->json, null, $this->options->formattingOptions);
$this->json = JsoncParser::applyEdits($this->json, $edits);
return $this;
}
public function toString(): string
{
return $this->json;
}
}
$config = new ConfigEditor('{}');
$config
->set(['app', 'name'], 'MyApplication')
->set(['app', 'version'], '2.0.0')
->set(['database', 'driver'], 'postgresql')
->set(['database', 'host'], 'localhost')
->set(['database', 'port'], 5432)
->set(['features', 'logging'], true)
->set(['features', 'caching'], true)
->format();
echo "Final configuration:\n";
echo $config->toString();
echo "\nReading value:\n";
echo "Database host: " . $config->get(['database', 'host']) . "\n";
echo "\n=== Examples Complete ===\n";