0
# JsonElement DOM
1
2
JSON Document Object Model providing type-safe programmatic access to JSON structures without requiring predefined data classes. The JsonElement hierarchy enables dynamic JSON manipulation, validation, and transformation.
3
4
## Capabilities
5
6
### JsonElement Base Class
7
8
Base sealed class for all JSON elements, enabling pattern matching and type-safe casting.
9
10
```kotlin { .api }
11
/**
12
* Base class for all JSON elements
13
* Represents any valid JSON value: object, array, primitive, or null
14
*/
15
@Serializable(JsonElementSerializer::class)
16
sealed class JsonElement
17
```
18
19
### JsonPrimitive - Primitive Values
20
21
Represents JSON primitive values: strings, numbers, booleans, and null.
22
23
```kotlin { .api }
24
/**
25
* Represents JSON primitive values (strings, numbers, booleans)
26
*/
27
@Serializable(JsonPrimitiveSerializer::class)
28
sealed class JsonPrimitive : JsonElement {
29
/** Whether this primitive should be serialized as a quoted string */
30
val isString: Boolean
31
/** Raw content of the primitive without quotes */
32
val content: String
33
}
34
35
/**
36
* Represents JSON null value
37
*/
38
@Serializable(JsonNullSerializer::class)
39
object JsonNull : JsonPrimitive {
40
override val isString: Boolean = false
41
override val content: String = "null"
42
}
43
```
44
45
### JsonObject - Object Values
46
47
Represents JSON objects as key-value maps.
48
49
```kotlin { .api }
50
/**
51
* Represents JSON objects as key-value pairs
52
* Implements Map<String, JsonElement> for convenient access
53
*/
54
@Serializable(JsonObjectSerializer::class)
55
class JsonObject(content: Map<String, JsonElement>) : JsonElement, Map<String, JsonElement>
56
```
57
58
**Usage Examples:**
59
60
```kotlin
61
import kotlinx.serialization.json.*
62
63
// Access object properties
64
val json = Json.parseToJsonElement("""{"name": "Alice", "age": 30}""")
65
val jsonObject = json.jsonObject
66
67
val name = jsonObject["name"]?.jsonPrimitive?.content // "Alice"
68
val age = jsonObject["age"]?.jsonPrimitive?.int // 30
69
70
// Iterate over properties
71
jsonObject.forEach { (key, value) ->
72
println("$key: $value")
73
}
74
75
// Check if key exists
76
if ("email" in jsonObject) {
77
val email = jsonObject["email"]?.jsonPrimitive?.content
78
}
79
```
80
81
### JsonArray - Array Values
82
83
Represents JSON arrays as ordered lists.
84
85
```kotlin { .api }
86
/**
87
* Represents JSON arrays as ordered lists of elements
88
* Implements List<JsonElement> for convenient access
89
*/
90
@Serializable(JsonArraySerializer::class)
91
class JsonArray(content: List<JsonElement>) : JsonElement, List<JsonElement>
92
```
93
94
**Usage Examples:**
95
96
```kotlin
97
import kotlinx.serialization.json.*
98
99
// Access array elements
100
val json = Json.parseToJsonElement("""[1, "hello", true, null]""")
101
val jsonArray = json.jsonArray
102
103
val firstNumber = jsonArray[0].jsonPrimitive.int // 1
104
val secondString = jsonArray[1].jsonPrimitive.content // "hello"
105
val thirdBoolean = jsonArray[2].jsonPrimitive.boolean // true
106
val fourthNull = jsonArray[3] // JsonNull
107
108
// Iterate over elements
109
jsonArray.forEachIndexed { index, element ->
110
println("Element $index: $element")
111
}
112
113
// Array operations
114
val size = jsonArray.size
115
val isEmpty = jsonArray.isEmpty()
116
```
117
118
### Factory Functions
119
120
Factory functions for creating JsonPrimitive instances from various Kotlin types.
121
122
```kotlin { .api }
123
/**
124
* Create JsonPrimitive from Boolean value
125
*/
126
fun JsonPrimitive(value: Boolean?): JsonPrimitive
127
128
/**
129
* Create JsonPrimitive from Number value
130
*/
131
fun JsonPrimitive(value: Number?): JsonPrimitive
132
133
/**
134
* Create JsonPrimitive from String value
135
*/
136
fun JsonPrimitive(value: String?): JsonPrimitive
137
138
/**
139
* Create JsonPrimitive from unsigned byte value
140
*/
141
@ExperimentalSerializationApi
142
fun JsonPrimitive(value: UByte): JsonPrimitive
143
144
/**
145
* Create JsonPrimitive from unsigned short value
146
*/
147
@ExperimentalSerializationApi
148
fun JsonPrimitive(value: UShort): JsonPrimitive
149
150
/**
151
* Create JsonPrimitive from unsigned int value
152
*/
153
@ExperimentalSerializationApi
154
fun JsonPrimitive(value: UInt): JsonPrimitive
155
156
/**
157
* Create JsonPrimitive from unsigned long value
158
*/
159
@ExperimentalSerializationApi
160
fun JsonPrimitive(value: ULong): JsonPrimitive
161
162
/**
163
* Create JsonNull from Nothing? (always null)
164
*/
165
@ExperimentalSerializationApi
166
fun JsonPrimitive(value: Nothing?): JsonNull
167
168
/**
169
* Create unquoted literal JsonPrimitive (for raw JSON values)
170
*/
171
@ExperimentalSerializationApi
172
fun JsonUnquotedLiteral(value: String?): JsonPrimitive
173
```
174
175
**Usage Examples:**
176
177
```kotlin
178
import kotlinx.serialization.json.*
179
180
// Create primitives from various types
181
val stringPrimitive = JsonPrimitive("Hello World")
182
val numberPrimitive = JsonPrimitive(42)
183
val booleanPrimitive = JsonPrimitive(true)
184
val nullPrimitive = JsonPrimitive(null as String?) // Creates JsonNull
185
186
// Create unquoted literals (experimental)
187
val rawJson = JsonUnquotedLiteral("true") // Creates unquoted boolean
188
```
189
190
### Type-Safe Casting Extensions
191
192
Extension properties for safe casting between JsonElement types.
193
194
```kotlin { .api }
195
/**
196
* Cast JsonElement to JsonPrimitive
197
* @throws IllegalArgumentException if element is not a JsonPrimitive
198
*/
199
val JsonElement.jsonPrimitive: JsonPrimitive
200
201
/**
202
* Cast JsonElement to JsonObject
203
* @throws IllegalArgumentException if element is not a JsonObject
204
*/
205
val JsonElement.jsonObject: JsonObject
206
207
/**
208
* Cast JsonElement to JsonArray
209
* @throws IllegalArgumentException if element is not a JsonArray
210
*/
211
val JsonElement.jsonArray: JsonArray
212
213
/**
214
* Cast JsonElement to JsonNull
215
* @throws IllegalArgumentException if element is not JsonNull
216
*/
217
val JsonElement.jsonNull: JsonNull
218
```
219
220
### Value Extraction Extensions
221
222
Extension properties for extracting typed values from JsonPrimitive.
223
224
```kotlin { .api }
225
/**
226
* Extract Int value from JsonPrimitive
227
* @throws IllegalArgumentException if primitive cannot be converted to Int
228
*/
229
val JsonPrimitive.int: Int
230
231
/**
232
* Extract Int value from JsonPrimitive, returning null if conversion fails
233
*/
234
val JsonPrimitive.intOrNull: Int?
235
236
/**
237
* Extract Long value from JsonPrimitive
238
* @throws IllegalArgumentException if primitive cannot be converted to Long
239
*/
240
val JsonPrimitive.long: Long
241
242
/**
243
* Extract Long value from JsonPrimitive, returning null if conversion fails
244
*/
245
val JsonPrimitive.longOrNull: Long?
246
247
/**
248
* Extract Double value from JsonPrimitive
249
* @throws IllegalArgumentException if primitive cannot be converted to Double
250
*/
251
val JsonPrimitive.double: Double
252
253
/**
254
* Extract Double value from JsonPrimitive, returning null if conversion fails
255
*/
256
val JsonPrimitive.doubleOrNull: Double?
257
258
/**
259
* Extract Float value from JsonPrimitive
260
* @throws IllegalArgumentException if primitive cannot be converted to Float
261
*/
262
val JsonPrimitive.float: Float
263
264
/**
265
* Extract Float value from JsonPrimitive, returning null if conversion fails
266
*/
267
val JsonPrimitive.floatOrNull: Float?
268
269
/**
270
* Extract Boolean value from JsonPrimitive
271
* @throws IllegalArgumentException if primitive cannot be converted to Boolean
272
*/
273
val JsonPrimitive.boolean: Boolean
274
275
/**
276
* Extract Boolean value from JsonPrimitive, returning null if conversion fails
277
*/
278
val JsonPrimitive.booleanOrNull: Boolean?
279
280
/**
281
* Extract String content from JsonPrimitive, returning null if JsonNull
282
*/
283
val JsonPrimitive.contentOrNull: String?
284
```
285
286
**Usage Examples:**
287
288
```kotlin
289
import kotlinx.serialization.json.*
290
291
val json = Json.parseToJsonElement("""
292
{
293
"name": "Alice",
294
"age": 30,
295
"height": 5.6,
296
"active": true,
297
"scores": [95, 87, 92],
298
"address": null
299
}
300
""")
301
302
val obj = json.jsonObject
303
304
// Safe casting and value extraction
305
val name = obj["name"]?.jsonPrimitive?.content // "Alice"
306
val age = obj["age"]?.jsonPrimitive?.int // 30
307
val height = obj["height"]?.jsonPrimitive?.double // 5.6
308
val active = obj["active"]?.jsonPrimitive?.boolean // true
309
310
// Handle nullable values
311
val address = obj["address"]?.jsonPrimitive?.contentOrNull // null
312
313
// Array access
314
val scores = obj["scores"]?.jsonArray
315
val firstScore = scores?.get(0)?.jsonPrimitive?.int // 95
316
317
// Safe extraction with null handling
318
val maybeAge = obj["age"]?.jsonPrimitive?.intOrNull // 30
319
val invalidAge = obj["name"]?.jsonPrimitive?.intOrNull // null (can't convert "Alice" to int)
320
```
321
322
### Pattern Matching
323
324
JsonElement's sealed class design enables exhaustive pattern matching.
325
326
```kotlin
327
import kotlinx.serialization.json.*
328
329
fun processJsonElement(element: JsonElement): String = when (element) {
330
is JsonObject -> "Object with ${element.size} properties"
331
is JsonArray -> "Array with ${element.size} elements"
332
is JsonPrimitive -> when {
333
element.isString -> "String: ${element.content}"
334
element == JsonNull -> "Null value"
335
element.booleanOrNull != null -> "Boolean: ${element.boolean}"
336
element.intOrNull != null -> "Integer: ${element.int}"
337
element.doubleOrNull != null -> "Number: ${element.double}"
338
else -> "Other primitive: ${element.content}"
339
}
340
}
341
```
342
343
## Common Patterns
344
345
### Deep JSON Navigation
346
347
```kotlin
348
import kotlinx.serialization.json.*
349
350
val json = Json.parseToJsonElement("""
351
{
352
"users": [
353
{
354
"profile": {
355
"name": "Alice",
356
"preferences": {
357
"theme": "dark"
358
}
359
}
360
}
361
]
362
}
363
""")
364
365
// Navigate deeply nested structure
366
val theme = json.jsonObject["users"]
367
?.jsonArray?.get(0)
368
?.jsonObject?.get("profile")
369
?.jsonObject?.get("preferences")
370
?.jsonObject?.get("theme")
371
?.jsonPrimitive?.content // "dark"
372
```
373
374
### JSON Validation
375
376
```kotlin
377
import kotlinx.serialization.json.*
378
379
fun validateUserJson(element: JsonElement): Boolean {
380
if (element !is JsonObject) return false
381
382
val name = element["name"]?.jsonPrimitive?.contentOrNull
383
val age = element["age"]?.jsonPrimitive?.intOrNull
384
val email = element["email"]?.jsonPrimitive?.contentOrNull
385
386
return name != null &&
387
age != null && age >= 0 &&
388
email != null && email.contains("@")
389
}
390
```
391
392
## Error Handling
393
394
JsonElement operations can throw exceptions:
395
396
- **IllegalArgumentException**: Type casting failures (e.g., calling `jsonObject` on JsonArray)
397
- **NumberFormatException**: Value extraction failures (e.g., calling `int` on non-numeric string)
398
- **IndexOutOfBoundsException**: Array access with invalid index
399
- **NoSuchElementException**: Map access with missing key (when using `getValue()`)
400
401
Use the null-safe extraction properties (`intOrNull`, `booleanOrNull`, etc.) to avoid exceptions when the conversion might fail.