0
# Content Parsing
1
2
The X-Content library provides pull-parsing capabilities for efficiently reading and navigating structured content with support for streaming operations across multiple formats.
3
4
## Capabilities
5
6
### XContentParser
7
8
Core interface for pull-based parsing of structured content.
9
10
```java { .api }
11
public interface XContentParser extends Closeable {
12
13
/**
14
* Parser tokens representing different content elements
15
*/
16
enum Token {
17
START_OBJECT, // {
18
END_OBJECT, // }
19
START_ARRAY, // [
20
END_ARRAY, // ]
21
FIELD_NAME, // field name in an object
22
VALUE_STRING, // string value
23
VALUE_NUMBER, // numeric value
24
VALUE_BOOLEAN, // boolean value
25
VALUE_EMBEDDED_OBJECT, // binary/embedded object
26
VALUE_NULL; // null value
27
28
/**
29
* Check if this token represents a value
30
* @return true if this token is a value token
31
*/
32
public boolean isValue();
33
}
34
35
/**
36
* Number types for numeric values
37
*/
38
enum NumberType {
39
INT, LONG, FLOAT, DOUBLE, BIG_INTEGER, BIG_DECIMAL
40
}
41
42
/**
43
* Advance to the next token
44
* @return the next token, or null if end of content
45
*/
46
Token nextToken() throws IOException;
47
48
/**
49
* Get the current token without advancing
50
* @return the current token
51
*/
52
Token currentToken();
53
54
/**
55
* Get the name of the current field (when currentToken is FIELD_NAME)
56
* @return the field name
57
*/
58
String currentName() throws IOException;
59
60
/**
61
* Advance to next token and return field name if it's FIELD_NAME
62
* @return field name if next token is FIELD_NAME, null otherwise
63
*/
64
String nextFieldName() throws IOException;
65
66
/**
67
* Skip all children of the current token (if it's START_OBJECT or START_ARRAY)
68
*/
69
void skipChildren() throws IOException;
70
71
/**
72
* Get the text representation of the current value
73
* @return text value of current token
74
*/
75
String text() throws IOException;
76
77
/**
78
* Get the text representation of the current value, or null if null token
79
* @return text value or null
80
*/
81
String textOrNull() throws IOException;
82
83
/**
84
* Get the current value as a generic Number
85
* @return Number representation of current numeric value
86
*/
87
Number numberValue() throws IOException;
88
89
/**
90
* Get the type of the current numeric value
91
* @return NumberType of current numeric value
92
*/
93
NumberType numberType() throws IOException;
94
95
/**
96
* Get the current value as an integer
97
* @return integer value
98
*/
99
int intValue() throws IOException;
100
101
/**
102
* Get the current value as a long
103
* @return long value
104
*/
105
long longValue() throws IOException;
106
107
/**
108
* Get the current value as a float
109
* @return float value
110
*/
111
float floatValue() throws IOException;
112
113
/**
114
* Get the current value as a double
115
* @return double value
116
*/
117
double doubleValue() throws IOException;
118
119
/**
120
* Get the current value as a boolean
121
* @return boolean value
122
*/
123
boolean booleanValue() throws IOException;
124
125
/**
126
* Get the current value as a byte array (for binary data)
127
* @return byte array
128
*/
129
byte[] binaryValue() throws IOException;
130
131
/**
132
* Parse the current object into a Map
133
* @return Map representation of current object
134
*/
135
Map<String, Object> map() throws IOException;
136
137
/**
138
* Parse the current object into a Map with specific ordering
139
* @param ordered whether to preserve field ordering
140
* @return Map representation of current object
141
*/
142
Map<String, Object> mapOrdered() throws IOException;
143
144
/**
145
* Parse the current array into a List
146
* @return List representation of current array
147
*/
148
List<Object> list() throws IOException;
149
150
/**
151
* Parse the current array into a List with specific ordering
152
* @param ordered whether to preserve ordering
153
* @return List representation of current array
154
*/
155
List<Object> listOrderedMap() throws IOException;
156
157
/**
158
* Get the current parsing location for error reporting
159
* @return XContentLocation with line/column information
160
*/
161
XContentLocation getTokenLocation();
162
163
/**
164
* Get the named XContent registry for this parser
165
* @return NamedXContentRegistry instance
166
*/
167
NamedXContentRegistry getXContentRegistry();
168
169
/**
170
* Get the deprecation handler for this parser
171
* @return DeprecationHandler instance
172
*/
173
DeprecationHandler getDeprecationHandler();
174
175
/**
176
* Get the REST API version for this parser
177
* @return RestApiVersion instance
178
*/
179
RestApiVersion getRestApiVersion();
180
}
181
```
182
183
**Usage Examples:**
184
185
```java
186
import org.elasticsearch.xcontent.*;
187
188
// Basic parsing example
189
String jsonContent = """
190
{
191
"name": "John Doe",
192
"age": 30,
193
"active": true,
194
"skills": ["Java", "Elasticsearch"],
195
"address": {
196
"street": "123 Main St",
197
"city": "New York"
198
}
199
}
200
""";
201
202
XContentParser parser = XContentType.JSON.xContent()
203
.createParser(XContentParserConfiguration.EMPTY, jsonContent);
204
205
// Navigate through tokens
206
while (parser.nextToken() != null) {
207
XContentParser.Token token = parser.currentToken();
208
209
switch (token) {
210
case FIELD_NAME:
211
String fieldName = parser.currentName();
212
System.out.println("Field: " + fieldName);
213
break;
214
case VALUE_STRING:
215
System.out.println("String value: " + parser.text());
216
break;
217
case VALUE_NUMBER:
218
System.out.println("Number value: " + parser.numberValue());
219
break;
220
case VALUE_BOOLEAN:
221
System.out.println("Boolean value: " + parser.booleanValue());
222
break;
223
case START_OBJECT:
224
System.out.println("Starting object");
225
break;
226
case END_OBJECT:
227
System.out.println("Ending object");
228
break;
229
case START_ARRAY:
230
System.out.println("Starting array");
231
break;
232
case END_ARRAY:
233
System.out.println("Ending array");
234
break;
235
}
236
}
237
parser.close();
238
239
// Parse specific field values
240
parser = XContentType.JSON.xContent()
241
.createParser(XContentParserConfiguration.EMPTY, jsonContent);
242
243
String name = null;
244
int age = 0;
245
List<String> skills = new ArrayList<>();
246
247
while (parser.nextToken() != null) {
248
if (parser.currentToken() == XContentParser.Token.FIELD_NAME) {
249
String fieldName = parser.currentName();
250
parser.nextToken(); // Move to the value
251
252
switch (fieldName) {
253
case "name":
254
name = parser.text();
255
break;
256
case "age":
257
age = parser.intValue();
258
break;
259
case "skills":
260
while (parser.nextToken() != XContentParser.Token.END_ARRAY) {
261
skills.add(parser.text());
262
}
263
break;
264
case "address":
265
// Parse nested object
266
Map<String, Object> address = parser.map();
267
System.out.println("Address: " + address);
268
break;
269
}
270
}
271
}
272
parser.close();
273
274
// Quick conversion to Map/List
275
parser = XContentType.JSON.xContent()
276
.createParser(XContentParserConfiguration.EMPTY, jsonContent);
277
parser.nextToken(); // Move to START_OBJECT
278
Map<String, Object> map = parser.map();
279
parser.close();
280
```
281
282
### XContentLocation
283
284
Location information for error reporting and debugging.
285
286
```java { .api }
287
/**
288
* Represents a location in XContent (line and column numbers)
289
*/
290
public record XContentLocation(int lineNumber, int columnNumber) {
291
292
/**
293
* Unknown location constant
294
*/
295
public static final XContentLocation UNKNOWN = new XContentLocation(-1, -1);
296
297
/**
298
* Get the line number (1-based)
299
* @return line number, or -1 if unknown
300
*/
301
public int lineNumber();
302
303
/**
304
* Get the column number (1-based)
305
* @return column number, or -1 if unknown
306
*/
307
public int columnNumber();
308
}
309
```
310
311
### Parser Creation
312
313
Methods for creating parsers from different input sources.
314
315
```java { .api }
316
public interface XContent {
317
318
/**
319
* Create parser from string content
320
* @param config parser configuration
321
* @param content string content to parse
322
* @return XContentParser instance
323
*/
324
XContentParser createParser(XContentParserConfiguration config, String content) throws IOException;
325
326
/**
327
* Create parser from input stream
328
* @param config parser configuration
329
* @param is input stream to parse
330
* @return XContentParser instance
331
*/
332
XContentParser createParser(XContentParserConfiguration config, InputStream is) throws IOException;
333
334
/**
335
* Create parser from byte array
336
* @param config parser configuration
337
* @param data byte array to parse
338
* @return XContentParser instance
339
*/
340
XContentParser createParser(XContentParserConfiguration config, byte[] data) throws IOException;
341
342
/**
343
* Create parser from byte array with offset and length
344
* @param config parser configuration
345
* @param data byte array to parse
346
* @param offset starting offset in the array
347
* @param length number of bytes to parse
348
* @return XContentParser instance
349
*/
350
XContentParser createParser(XContentParserConfiguration config, byte[] data, int offset, int length) throws IOException;
351
352
/**
353
* Create parser from Reader
354
* @param config parser configuration
355
* @param reader Reader to parse from
356
* @return XContentParser instance
357
*/
358
XContentParser createParser(XContentParserConfiguration config, Reader reader) throws IOException;
359
}
360
```
361
362
### Specialized Parsers
363
364
Extended parser implementations for specific use cases.
365
366
```java { .api }
367
/**
368
* Parser wrapper that filters content based on include/exclude patterns
369
*/
370
public class FilterXContentParser implements XContentParser {
371
/**
372
* Create a filtering parser
373
* @param parser the underlying parser
374
* @param includes field patterns to include
375
* @param excludes field patterns to exclude
376
*/
377
public FilterXContentParser(XContentParser parser, Set<String> includes, Set<String> excludes);
378
}
379
380
/**
381
* Parser that flattens nested object structures
382
*/
383
public class FlatteningXContentParser implements XContentParser {
384
/**
385
* Create a flattening parser
386
* @param parser the underlying parser
387
*/
388
public FlatteningXContentParser(XContentParser parser);
389
}
390
391
/**
392
* Parser that copies content to another parser while parsing
393
*/
394
public class CopyingXContentParser implements XContentParser {
395
/**
396
* Create a copying parser
397
* @param parser the source parser
398
* @param builder the builder to copy content to
399
*/
400
public CopyingXContentParser(XContentParser parser, XContentBuilder builder);
401
}
402
403
/**
404
* Parser backed by a Map instead of content stream
405
*/
406
public class MapXContentParser extends AbstractXContentParser {
407
/**
408
* Create a parser from a Map
409
* @param map the map to parse
410
* @param registry named content registry
411
* @param deprecationHandler deprecation handler
412
* @param contentType content type
413
*/
414
public MapXContentParser(NamedXContentRegistry registry, DeprecationHandler deprecationHandler,
415
Map<String, Object> map, XContentType contentType);
416
}
417
```
418
419
### Utility Methods
420
421
```java { .api }
422
public class XContentUtils {
423
424
/**
425
* Convert a parser token to its corresponding Object value
426
* @param parser the parser
427
* @param token the token to convert
428
* @return Object representation of the token value
429
*/
430
public static Object readValue(XContentParser parser, XContentParser.Token token) throws IOException;
431
}
432
```