0
# Configuration
1
2
Default configuration presets and validation error handling for different API versions and usage patterns.
3
4
## Capabilities
5
6
### Default Configuration Presets
7
8
The defaults module provides version-specific configuration presets that match different API behaviors and compatibility levels.
9
10
```javascript { .api }
11
const defaults: {
12
"0.1": DefaultOptions;
13
"0.2": DefaultOptions;
14
};
15
16
interface DefaultOptions {
17
explicitArray: boolean;
18
ignoreAttrs: boolean;
19
mergeAttrs: boolean;
20
normalize: boolean;
21
normalizeTags: boolean;
22
attrkey: string;
23
charkey: string;
24
explicitCharkey: boolean;
25
trim: boolean;
26
explicitRoot: boolean;
27
emptyTag: string;
28
strict: boolean;
29
}
30
```
31
32
**Usage Examples:**
33
34
```javascript
35
const xml2js = require('xml2js');
36
37
// Access default configurations
38
console.log(xml2js.defaults['0.1']);
39
console.log(xml2js.defaults['0.2']);
40
41
// Use version-specific defaults
42
const parser01 = new xml2js.Parser(xml2js.defaults['0.1']);
43
const parser02 = new xml2js.Parser(xml2js.defaults['0.2']);
44
45
// Extend defaults with custom options
46
const customOptions = Object.assign({}, xml2js.defaults['0.2'], {
47
trim: true,
48
parseNumbers: true,
49
tagNameProcessors: [xml2js.processors.firstCharLowerCase]
50
});
51
52
const customParser = new xml2js.Parser(customOptions);
53
```
54
55
### Version 0.1 Defaults
56
57
Legacy configuration preset for backwards compatibility with older xml2js behavior.
58
59
```javascript { .api }
60
const version01Defaults: {
61
explicitArray: false;
62
ignoreAttrs: false;
63
mergeAttrs: false;
64
normalize: true;
65
normalizeTags: false;
66
attrkey: "@";
67
charkey: "#";
68
explicitCharkey: false;
69
trim: true;
70
explicitRoot: false;
71
emptyTag: "";
72
strict: true;
73
validator: null;
74
xmlns: false;
75
explicitChildren: false;
76
childkey: "@@";
77
charsAsChildren: false;
78
includeWhiteChars: false;
79
async: false;
80
attrNameProcessors: null;
81
attrValueProcessors: null;
82
tagNameProcessors: null;
83
valueProcessors: null;
84
};
85
```
86
87
**Characteristics of Version 0.1:**
88
- `explicitArray: false` - Single child elements are not wrapped in arrays
89
- `ignoreAttrs: false` - XML attributes are preserved
90
- `normalize: true` and `trim: true` - Text processing enabled by default
91
- `explicitRoot: false` - Root element not wrapped in result
92
- Different attribute/character keys: `@` for attributes, `#` for character content
93
94
**Usage Examples:**
95
96
```javascript
97
const xml2js = require('xml2js');
98
99
// Parser with 0.1 defaults
100
const legacyParser = new xml2js.Parser(xml2js.defaults['0.1']);
101
102
const xmlString = '<person name="John"><age>30</age></person>';
103
legacyParser.parseString(xmlString, (err, result) => {
104
if (!err) {
105
console.log(result);
106
// With 0.1 defaults: { person: { '@': { name: 'John' }, age: '30' } }
107
// Note: attributes preserved with @ key, no root wrapper
108
}
109
});
110
```
111
112
### Version 0.2 Defaults
113
114
Current default configuration providing more comprehensive XML handling with attribute support.
115
116
```javascript { .api }
117
const version02Defaults: {
118
explicitArray: true;
119
ignoreAttrs: false;
120
mergeAttrs: false;
121
normalize: false;
122
normalizeTags: false;
123
attrkey: "$";
124
charkey: "_";
125
explicitCharkey: false;
126
trim: false;
127
explicitRoot: true;
128
emptyTag: "";
129
strict: true;
130
validator: null;
131
xmlns: false;
132
explicitChildren: false;
133
preserveChildrenOrder: false;
134
childkey: "$$";
135
charsAsChildren: false;
136
includeWhiteChars: false;
137
async: false;
138
attrNameProcessors: null;
139
attrValueProcessors: null;
140
tagNameProcessors: null;
141
valueProcessors: null;
142
rootName: "root";
143
xmldec: {
144
version: "1.0";
145
encoding: "UTF-8";
146
standalone: true;
147
};
148
doctype: null;
149
renderOpts: {
150
pretty: true;
151
indent: " ";
152
newline: "\n";
153
};
154
headless: false;
155
chunkSize: 10000;
156
cdata: false;
157
};
158
```
159
160
**Characteristics of Version 0.2:**
161
- `explicitArray: true` - All child elements are wrapped in arrays for consistency
162
- `ignoreAttrs: false` - XML attributes are preserved and accessible
163
- More predictable structure for programmatic processing
164
165
**Usage Examples:**
166
167
```javascript
168
const xml2js = require('xml2js');
169
170
// Parser with 0.2 defaults (current default)
171
const modernParser = new xml2js.Parser(xml2js.defaults['0.2']);
172
173
const xmlString = '<person name="John"><age>30</age></person>';
174
modernParser.parseString(xmlString, (err, result) => {
175
if (!err) {
176
console.log(result);
177
// With 0.2 defaults: { person: { $: { name: 'John' }, age: ['30'] } }
178
// Note: attributes preserved, age is an array
179
}
180
});
181
```
182
183
### Custom Configuration Patterns
184
185
```javascript
186
const xml2js = require('xml2js');
187
188
// Web API friendly configuration
189
const webApiConfig = Object.assign({}, xml2js.defaults['0.2'], {
190
explicitArray: false, // Simpler structure
191
mergeAttrs: true, // Merge attributes with content
192
trim: true, // Clean whitespace
193
tagNameProcessors: [xml2js.processors.firstCharLowerCase],
194
valueProcessors: [xml2js.processors.parseNumbers, xml2js.processors.parseBooleans]
195
});
196
197
// Configuration for processing RSS/Atom feeds
198
const feedConfig = Object.assign({}, xml2js.defaults['0.2'], {
199
explicitArray: false,
200
trim: true,
201
normalize: true,
202
tagNameProcessors: [xml2js.processors.normalize],
203
valueProcessors: [xml2js.processors.parseNumbers]
204
});
205
206
// Configuration for SOAP/XML services
207
const soapConfig = Object.assign({}, xml2js.defaults['0.2'], {
208
explicitArray: false,
209
tagNameProcessors: [xml2js.processors.stripPrefix],
210
xmlns: true, // Preserve namespace information
211
explicitRoot: false
212
});
213
```
214
215
## ValidationError Class
216
217
Custom error class for XML validation and parsing failures, extending the standard JavaScript Error class.
218
219
```javascript { .api }
220
/**
221
* Custom error class for XML validation failures
222
*/
223
class ValidationError extends Error {
224
/**
225
* Create a ValidationError
226
* @param message - Error message describing the validation failure
227
*/
228
constructor(message: string);
229
}
230
```
231
232
**Usage Examples:**
233
234
```javascript
235
const xml2js = require('xml2js');
236
237
// ValidationError is thrown for validation failures
238
const parser = new xml2js.Parser({
239
validator: (xpath, currentValue, newValue) => {
240
// Custom validation logic
241
if (xpath === '/product/price' && isNaN(parseFloat(newValue))) {
242
throw new xml2js.ValidationError(`Invalid price value: ${newValue}`);
243
}
244
return newValue;
245
}
246
});
247
248
const invalidXml = '<product><price>not-a-number</price></product>';
249
250
parser.parseString(invalidXml, (err, result) => {
251
if (err instanceof xml2js.ValidationError) {
252
console.error('Validation failed:', err.message);
253
// Handle validation error specifically
254
} else if (err) {
255
console.error('Parse error:', err.message);
256
// Handle other parsing errors
257
} else {
258
console.log('Parse successful:', result);
259
}
260
});
261
262
// Using with promises
263
async function parseWithValidation(xmlString) {
264
try {
265
const result = await parser.parseStringPromise(xmlString);
266
return result;
267
} catch (error) {
268
if (error instanceof xml2js.ValidationError) {
269
console.error('Validation error:', error.message);
270
throw new Error(`XML validation failed: ${error.message}`);
271
}
272
throw error;
273
}
274
}
275
```
276
277
### Custom Validation with ValidationError
278
279
```javascript
280
const xml2js = require('xml2js');
281
282
// Complex validation example
283
function createValidatingParser(schema) {
284
return new xml2js.Parser({
285
validator: (xpath, currentValue, newValue) => {
286
const rule = schema[xpath];
287
if (rule) {
288
// Type validation
289
if (rule.type === 'number' && isNaN(parseFloat(newValue))) {
290
throw new xml2js.ValidationError(`Expected number at ${xpath}, got: ${newValue}`);
291
}
292
293
// Range validation
294
if (rule.type === 'number' && rule.min !== undefined) {
295
const numValue = parseFloat(newValue);
296
if (numValue < rule.min) {
297
throw new xml2js.ValidationError(`Value ${numValue} at ${xpath} is below minimum ${rule.min}`);
298
}
299
}
300
301
// String length validation
302
if (rule.type === 'string' && rule.maxLength !== undefined) {
303
if (newValue.length > rule.maxLength) {
304
throw new xml2js.ValidationError(`String at ${xpath} exceeds maximum length ${rule.maxLength}`);
305
}
306
}
307
308
// Required field validation
309
if (rule.required && (!newValue || newValue.trim() === '')) {
310
throw new xml2js.ValidationError(`Required field ${xpath} is empty`);
311
}
312
}
313
314
return newValue;
315
}
316
});
317
}
318
319
// Define validation schema
320
const productSchema = {
321
'/product/id': { type: 'number', required: true, min: 1 },
322
'/product/name': { type: 'string', required: true, maxLength: 100 },
323
'/product/price': { type: 'number', required: true, min: 0 },
324
'/product/description': { type: 'string', maxLength: 500 }
325
};
326
327
const validatingParser = createValidatingParser(productSchema);
328
329
// Test with valid XML
330
const validXml = `
331
<product>
332
<id>123</id>
333
<name>Laptop</name>
334
<price>999.99</price>
335
<description>High-performance laptop</description>
336
</product>
337
`;
338
339
// Test with invalid XML
340
const invalidXml = `
341
<product>
342
<id>0</id>
343
<name></name>
344
<price>-100</price>
345
<description>${'x'.repeat(600)}</description>
346
</product>
347
`;
348
349
validatingParser.parseString(validXml, (err, result) => {
350
if (err instanceof xml2js.ValidationError) {
351
console.error('Validation failed:', err.message);
352
} else if (!err) {
353
console.log('Valid XML parsed successfully');
354
}
355
});
356
```
357
358
## Configuration Best Practices
359
360
### Choosing the Right Defaults
361
362
```javascript
363
const xml2js = require('xml2js');
364
365
// For simple XML consumption (e.g., configuration files)
366
const simpleConfig = xml2js.defaults['0.1']; // No arrays, ignores attributes
367
368
// For comprehensive XML processing (e.g., APIs, complex documents)
369
const comprehensiveConfig = xml2js.defaults['0.2']; // Preserves structure
370
371
// For web applications (JSON-like structure)
372
const webConfig = Object.assign({}, xml2js.defaults['0.2'], {
373
explicitArray: false,
374
mergeAttrs: true
375
});
376
```
377
378
### Performance Considerations
379
380
```javascript
381
const xml2js = require('xml2js');
382
383
// High-performance parsing for large documents
384
const performanceConfig = {
385
// Minimal processing
386
explicitArray: false,
387
ignoreAttrs: true,
388
trim: false,
389
normalize: false,
390
391
// No text processors to avoid overhead
392
tagNameProcessors: null,
393
valueProcessors: null,
394
395
// Async processing for large documents
396
async: true,
397
chunkSize: 50000
398
};
399
400
// Memory-efficient parsing
401
const memoryEfficientConfig = {
402
explicitArray: false,
403
explicitRoot: false,
404
trim: true,
405
emptyTag: null, // Don't create empty values
406
strict: false // More lenient parsing
407
};
408
```
409
410
### Error Handling Strategies
411
412
```javascript
413
const xml2js = require('xml2js');
414
415
// Comprehensive error handling
416
function createRobustParser(options = {}) {
417
const defaultOptions = Object.assign({}, xml2js.defaults['0.2'], {
418
// Enable strict validation
419
strict: true,
420
421
// Custom validator for business logic
422
validator: (xpath, currentValue, newValue) => {
423
try {
424
// Apply custom validation rules here
425
return newValue;
426
} catch (validationError) {
427
throw new xml2js.ValidationError(`Validation failed at ${xpath}: ${validationError.message}`);
428
}
429
}
430
}, options);
431
432
return new xml2js.Parser(defaultOptions);
433
}
434
435
// Usage with comprehensive error handling
436
async function safeParseXML(xmlString, options) {
437
const parser = createRobustParser(options);
438
439
try {
440
const result = await parser.parseStringPromise(xmlString);
441
return { success: true, data: result };
442
} catch (error) {
443
if (error instanceof xml2js.ValidationError) {
444
return {
445
success: false,
446
error: 'validation',
447
message: error.message
448
};
449
} else {
450
return {
451
success: false,
452
error: 'parsing',
453
message: error.message
454
};
455
}
456
}
457
}
458
```