0
# JsonElement Tree API
1
2
Programmatic JSON tree manipulation with a rich hierarchy of JsonElement types for building and accessing JSON structures. The JsonElement API provides a type-safe way to work with JSON data at the tree level.
3
4
## Capabilities
5
6
### JsonElement Hierarchy
7
8
The base class and hierarchy for representing JSON values as a tree structure.
9
10
```kotlin { .api }
11
/**
12
* Represents a JSON element - base class for all JSON values
13
*/
14
sealed class JsonElement
15
16
/**
17
* Represents JSON primitive values (strings, numbers, booleans, null)
18
*/
19
abstract class JsonPrimitive : JsonElement {
20
/**
21
* Raw string content of the primitive value
22
*/
23
abstract val content: String
24
25
/**
26
* True if this primitive represents a JSON string value
27
*/
28
val isString: Boolean
29
}
30
31
/**
32
* Represents JSON objects with key-value pairs
33
*/
34
class JsonObject(val content: Map<String, JsonElement>) : JsonElement, Map<String, JsonElement>
35
36
/**
37
* Represents JSON arrays
38
*/
39
class JsonArray(val content: List<JsonElement>) : JsonElement, List<JsonElement>
40
41
/**
42
* Represents JSON null value
43
*/
44
object JsonNull : JsonPrimitive()
45
```
46
47
### JsonElement Type Conversion Extensions
48
49
Convenience extension properties for type-safe conversion between JsonElement types.
50
51
```kotlin { .api }
52
/**
53
* Convenience method to get current element as JsonPrimitive
54
* @throws IllegalArgumentException if current element is not a JsonPrimitive
55
*/
56
val JsonElement.jsonPrimitive: JsonPrimitive
57
58
/**
59
* Convenience method to get current element as JsonObject
60
* @throws IllegalArgumentException if current element is not a JsonObject
61
*/
62
val JsonElement.jsonObject: JsonObject
63
64
/**
65
* Convenience method to get current element as JsonArray
66
* @throws IllegalArgumentException if current element is not a JsonArray
67
*/
68
val JsonElement.jsonArray: JsonArray
69
70
/**
71
* Convenience method to get current element as JsonNull
72
* @throws IllegalArgumentException if current element is not a JsonNull
73
*/
74
val JsonElement.jsonNull: JsonNull
75
```
76
77
**Usage Examples:**
78
79
```kotlin
80
val json = Json.Default
81
val jsonString = """{"users": [{"name": "Alice", "age": 25}, {"name": "Bob", "age": null}]}"""
82
val element = json.parseToJsonElement(jsonString)
83
84
// Access nested elements with type safety
85
val rootObject = element.jsonObject
86
val usersArray = rootObject["users"]!!.jsonArray
87
val firstUser = usersArray[0].jsonObject
88
val userName = firstUser["name"]!!.jsonPrimitive.content
89
val userAge = firstUser["age"]!!.jsonPrimitive.int
90
91
println("User: $userName, Age: $userAge") // User: Alice, Age: 25
92
93
// Handle null values
94
val secondUserAge = usersArray[1].jsonObject["age"]
95
if (secondUserAge is JsonNull) {
96
println("Second user age is null")
97
}
98
```
99
100
### JsonPrimitive Factory Functions
101
102
Create JsonPrimitive instances from various Kotlin types.
103
104
```kotlin { .api }
105
/**
106
* Creates JsonPrimitive from Boolean value
107
*/
108
fun JsonPrimitive(value: Boolean?): JsonPrimitive
109
110
/**
111
* Creates JsonPrimitive from Number value
112
*/
113
fun JsonPrimitive(value: Number?): JsonPrimitive
114
115
/**
116
* Creates JsonPrimitive from String value
117
*/
118
fun JsonPrimitive(value: String?): JsonPrimitive
119
120
/**
121
* Creates JsonPrimitive from unsigned integer types
122
*/
123
@ExperimentalSerializationApi
124
fun JsonPrimitive(value: UByte): JsonPrimitive
125
@ExperimentalSerializationApi
126
fun JsonPrimitive(value: UShort): JsonPrimitive
127
@ExperimentalSerializationApi
128
fun JsonPrimitive(value: UInt): JsonPrimitive
129
@ExperimentalSerializationApi
130
fun JsonPrimitive(value: ULong): JsonPrimitive
131
132
/**
133
* Creates unquoted JSON literal (experimental)
134
* Be aware that it is possible to create invalid JSON using this function
135
* @throws JsonEncodingException if value == "null"
136
*/
137
@ExperimentalSerializationApi
138
fun JsonUnquotedLiteral(value: String?): JsonPrimitive
139
```
140
141
**Usage Examples:**
142
143
```kotlin
144
// Create primitive values
145
val stringPrimitive = JsonPrimitive("hello")
146
val numberPrimitive = JsonPrimitive(42)
147
val boolPrimitive = JsonPrimitive(true)
148
val nullPrimitive = JsonPrimitive(null as String?) // Creates JsonNull
149
150
// Unsigned integer support
151
val uintPrimitive = JsonPrimitive(42u)
152
val ulongPrimitive = JsonPrimitive(9223372036854775808UL)
153
154
// Check primitive types
155
println(stringPrimitive.isString) // true
156
println(numberPrimitive.isString) // false
157
println(stringPrimitive.content) // "hello"
158
println(numberPrimitive.content) // "42"
159
160
// Unquoted literals for precise numbers
161
val preciseNumber = JsonUnquotedLiteral("123.456789012345678901234567890")
162
val largeInteger = JsonUnquotedLiteral("12345678901234567890123456789")
163
```
164
165
### JsonPrimitive Value Accessors
166
167
Type-safe accessors for extracting values from JsonPrimitive instances.
168
169
```kotlin { .api }
170
/**
171
* Content as string, or null if this is JsonNull
172
*/
173
val JsonPrimitive.contentOrNull: String?
174
175
/**
176
* Returns content as Int
177
* @throws NumberFormatException if not a valid representation
178
*/
179
val JsonPrimitive.int: Int
180
181
/**
182
* Returns content as Int or null if invalid
183
*/
184
val JsonPrimitive.intOrNull: Int?
185
186
/**
187
* Returns content as Long
188
* @throws NumberFormatException if not a valid representation
189
*/
190
val JsonPrimitive.long: Long
191
192
/**
193
* Returns content as Long or null if invalid
194
*/
195
val JsonPrimitive.longOrNull: Long?
196
197
/**
198
* Returns content as Double
199
* @throws NumberFormatException if not a valid representation
200
*/
201
val JsonPrimitive.double: Double
202
203
/**
204
* Returns content as Double or null if invalid
205
*/
206
val JsonPrimitive.doubleOrNull: Double?
207
208
/**
209
* Returns content as Float
210
* @throws NumberFormatException if not a valid representation
211
*/
212
val JsonPrimitive.float: Float
213
214
/**
215
* Returns content as Float or null if invalid
216
*/
217
val JsonPrimitive.floatOrNull: Float?
218
219
/**
220
* Returns content as Boolean
221
* @throws IllegalStateException if not a valid boolean representation
222
*/
223
val JsonPrimitive.boolean: Boolean
224
225
/**
226
* Returns content as Boolean or null if invalid
227
*/
228
val JsonPrimitive.booleanOrNull: Boolean?
229
```
230
231
**Usage Examples:**
232
233
```kotlin
234
val json = Json.Default
235
val element = json.parseToJsonElement("""
236
{
237
"name": "Alice",
238
"age": 25,
239
"height": 5.6,
240
"isActive": true,
241
"score": null
242
}
243
""")
244
245
val obj = element.jsonObject
246
247
// Safe type conversions
248
val name = obj["name"]!!.jsonPrimitive.content // "Alice"
249
val age = obj["age"]!!.jsonPrimitive.int // 25
250
val height = obj["height"]!!.jsonPrimitive.double // 5.6
251
val isActive = obj["isActive"]!!.jsonPrimitive.boolean // true
252
253
// Handle null values
254
val score = obj["score"]!!.jsonPrimitive.contentOrNull // null
255
256
// Safe conversions with null fallback
257
val invalidAge = JsonPrimitive("not-a-number").intOrNull // null
258
val validAge = JsonPrimitive("30").intOrNull // 30
259
260
// Check if primitive contains actual content
261
val nullPrimitive = JsonNull
262
println(nullPrimitive.contentOrNull) // null
263
println(nullPrimitive.content) // "null"
264
```
265
266
```kotlin { .api }
267
/**
268
* JsonPrimitive value accessors with exception-throwing variants
269
*/
270
val JsonPrimitive.int: Int
271
val JsonPrimitive.intOrNull: Int?
272
val JsonPrimitive.long: Long
273
val JsonPrimitive.longOrNull: Long?
274
val JsonPrimitive.double: Double
275
val JsonPrimitive.doubleOrNull: Double?
276
val JsonPrimitive.float: Float
277
val JsonPrimitive.floatOrNull: Float?
278
val JsonPrimitive.boolean: Boolean
279
val JsonPrimitive.booleanOrNull: Boolean?
280
```
281
282
**Usage Examples:**
283
284
```kotlin
285
val numberElement = JsonPrimitive(123)
286
val boolElement = JsonPrimitive(true)
287
val stringElement = JsonPrimitive("456")
288
289
// Safe extraction
290
val intValue = numberElement.int // 123
291
val boolValue = boolElement.boolean // true
292
val intFromString = stringElement.int // 456 (parsed from string)
293
294
// Null-safe extraction
295
val safeInt = numberElement.intOrNull // 123
296
val safeFloat = boolElement.floatOrNull // null (can't convert boolean to float)
297
298
// Working with JsonNull
299
val nullElement = JsonNull
300
val nullInt = nullElement.intOrNull // null
301
val nullContent = nullElement.contentOrNull // null
302
```
303
304
### JsonObject Operations
305
306
JsonObject implements Map interface providing standard map operations for JSON objects.
307
308
```kotlin { .api }
309
/**
310
* JsonObject constructor and map operations
311
*/
312
class JsonObject(val content: Map<String, JsonElement>) : JsonElement, Map<String, JsonElement> {
313
// Inherits all Map operations:
314
// get(key), containsKey(key), isEmpty(), size, keys, values, entries, etc.
315
}
316
```
317
318
**Usage Examples:**
319
320
```kotlin
321
// Create JsonObject
322
val jsonObject = JsonObject(mapOf(
323
"name" to JsonPrimitive("Alice"),
324
"age" to JsonPrimitive(30),
325
"isActive" to JsonPrimitive(true)
326
))
327
328
// Access properties
329
val name = jsonObject["name"]?.jsonPrimitive?.content // "Alice"
330
val age = jsonObject["age"]?.jsonPrimitive?.int // 30
331
val active = jsonObject["isActive"]?.jsonPrimitive?.boolean // true
332
333
// Check existence
334
if ("email" in jsonObject) {
335
val email = jsonObject["email"]?.jsonPrimitive?.content
336
}
337
338
// Iterate over properties
339
for ((key, value) in jsonObject) {
340
println("$key: $value")
341
}
342
343
// Get all keys and values
344
val keys = jsonObject.keys // Set<String>
345
val values = jsonObject.values // Collection<JsonElement>
346
val entries = jsonObject.entries // Set<Map.Entry<String, JsonElement>>
347
```
348
349
### JsonArray Operations
350
351
JsonArray implements List interface providing standard list operations for JSON arrays.
352
353
```kotlin { .api }
354
/**
355
* JsonArray constructor and list operations
356
*/
357
class JsonArray(val content: List<JsonElement>) : JsonElement, List<JsonElement> {
358
// Inherits all List operations:
359
// get(index), size, isEmpty(), iterator(), contains(element), etc.
360
}
361
```
362
363
**Usage Examples:**
364
365
```kotlin
366
// Create JsonArray
367
val jsonArray = JsonArray(listOf(
368
JsonPrimitive("apple"),
369
JsonPrimitive("banana"),
370
JsonPrimitive("cherry")
371
))
372
373
// Access elements
374
val firstItem = jsonArray[0].jsonPrimitive.content // "apple"
375
val secondItem = jsonArray[1].jsonPrimitive.content // "banana"
376
377
// Check size and bounds
378
val size = jsonArray.size // 3
379
val isEmpty = jsonArray.isEmpty() // false
380
381
// Iterate over elements
382
for (element in jsonArray) {
383
val value = element.jsonPrimitive.content
384
println(value)
385
}
386
387
// Convert to regular list
388
val stringList = jsonArray.map { it.jsonPrimitive.content }
389
// Result: ["apple", "banana", "cherry"]
390
391
// Check if element exists
392
val containsApple = jsonArray.any {
393
it.jsonPrimitive.content == "apple"
394
} // true
395
```
396
397
### Element Type Checking and Casting
398
399
Safe type checking and casting utilities for JsonElement instances.
400
401
```kotlin { .api }
402
/**
403
* Type checking extension properties
404
*/
405
val JsonElement.jsonPrimitive: JsonPrimitive
406
val JsonElement.jsonObject: JsonObject
407
val JsonElement.jsonArray: JsonArray
408
val JsonElement.jsonNull: JsonNull
409
```
410
411
**Usage Examples:**
412
413
```kotlin
414
fun processJsonElement(element: JsonElement) {
415
when {
416
element is JsonPrimitive -> {
417
println("Primitive: ${element.content}")
418
419
// Safe casting
420
val primitive = element.jsonPrimitive
421
if (primitive.isString) {
422
println("String value: ${primitive.content}")
423
} else {
424
val numValue = primitive.doubleOrNull
425
println("Numeric value: $numValue")
426
}
427
}
428
429
element is JsonObject -> {
430
println("Object with ${element.size} properties")
431
val obj = element.jsonObject
432
obj.forEach { (key, value) ->
433
println(" $key: $value")
434
}
435
}
436
437
element is JsonArray -> {
438
println("Array with ${element.size} elements")
439
val array = element.jsonArray
440
array.forEachIndexed { index, value ->
441
println(" [$index]: $value")
442
}
443
}
444
445
element is JsonNull -> {
446
println("Null value")
447
}
448
}
449
}
450
451
// Safe casting example
452
fun extractStringValue(element: JsonElement): String? {
453
return (element as? JsonPrimitive)?.takeIf { it.isString }?.content
454
}
455
456
fun extractObjectProperty(element: JsonElement, key: String): JsonElement? {
457
return (element as? JsonObject)?.get(key)
458
}
459
```
460
461
### Complex Tree Navigation
462
463
Working with nested JSON structures using the element API.
464
465
**Usage Examples:**
466
467
```kotlin
468
// Complex nested structure
469
val complexJson = JsonObject(mapOf(
470
"user" to JsonObject(mapOf(
471
"id" to JsonPrimitive(123),
472
"profile" to JsonObject(mapOf(
473
"name" to JsonPrimitive("Alice"),
474
"emails" to JsonArray(listOf(
475
JsonPrimitive("alice@work.com"),
476
JsonPrimitive("alice@personal.com")
477
))
478
))
479
)),
480
"settings" to JsonObject(mapOf(
481
"theme" to JsonPrimitive("dark"),
482
"notifications" to JsonPrimitive(true)
483
))
484
))
485
486
// Navigate nested structure
487
val userId = complexJson["user"]
488
?.jsonObject?.get("id")
489
?.jsonPrimitive?.int // 123
490
491
val userName = complexJson["user"]
492
?.jsonObject?.get("profile")
493
?.jsonObject?.get("name")
494
?.jsonPrimitive?.content // "Alice"
495
496
val firstEmail = complexJson["user"]
497
?.jsonObject?.get("profile")
498
?.jsonObject?.get("emails")
499
?.jsonArray?.get(0)
500
?.jsonPrimitive?.content // "alice@work.com"
501
502
val theme = complexJson["settings"]
503
?.jsonObject?.get("theme")
504
?.jsonPrimitive?.content // "dark"
505
506
// Safe navigation with null checks
507
fun extractUserName(json: JsonElement): String? {
508
return (json as? JsonObject)
509
?.get("user")?.let { it as? JsonObject }
510
?.get("profile")?.let { it as? JsonObject }
511
?.get("name")?.let { it as? JsonPrimitive }
512
?.content
513
}
514
```
515
516
### Creating JsonElement Trees Programmatically
517
518
Build JsonElement structures programmatically for dynamic JSON generation.
519
520
**Usage Examples:**
521
522
```kotlin
523
// Build a user object programmatically
524
fun createUserJson(id: Int, name: String, emails: List<String>): JsonObject {
525
return JsonObject(mapOf(
526
"id" to JsonPrimitive(id),
527
"name" to JsonPrimitive(name),
528
"emails" to JsonArray(emails.map { JsonPrimitive(it) }),
529
"isActive" to JsonPrimitive(true),
530
"lastLogin" to JsonNull
531
))
532
}
533
534
val userJson = createUserJson(
535
id = 456,
536
name = "Bob",
537
emails = listOf("bob@example.com", "bob2@example.com")
538
)
539
540
// Convert to string for transmission
541
val json = Json.Default
542
val jsonString = json.encodeToString(JsonElement.serializer(), userJson)
543
544
// Build conditional structure
545
fun createResponseJson(success: Boolean, data: Any? = null, error: String? = null): JsonObject {
546
val elements = mutableMapOf<String, JsonElement>(
547
"success" to JsonPrimitive(success),
548
"timestamp" to JsonPrimitive(System.currentTimeMillis())
549
)
550
551
if (success && data != null) {
552
elements["data"] = json.encodeToJsonElement(data)
553
}
554
555
if (!success && error != null) {
556
elements["error"] = JsonPrimitive(error)
557
}
558
559
return JsonObject(elements)
560
}
561
```