Simple XML to JavaScript object converter.
Built-in text processing functions for common XML data transformations including normalization, type conversion, and namespace handling.
The processors module provides built-in text processing functions that can be used with parser and builder options to transform XML data during parsing.
const processors: {
normalize: (str: string) => string;
firstCharLowerCase: (str: string) => string;
stripPrefix: (str: string) => string;
parseNumbers: (str: string) => string | number;
parseBooleans: (str: string) => string | boolean;
};Usage Examples:
const xml2js = require('xml2js');
// Access processors
const { processors } = xml2js;
// Use processors individually
console.log(processors.normalize('HELLO WORLD')); // 'hello world'
console.log(processors.firstCharLowerCase('UserName')); // 'userName'
console.log(processors.stripPrefix('ns:ElementName')); // 'ElementName'
console.log(processors.parseNumbers('42')); // 42 (number)
console.log(processors.parseBooleans('true')); // true (boolean)
// Use with parser options
const parserOptions = {
tagNameProcessors: [processors.firstCharLowerCase],
valueProcessors: [processors.parseNumbers, processors.parseBooleans],
attrNameProcessors: [processors.normalize]
};
const parser = new xml2js.Parser(parserOptions);Converts strings to lowercase for case-insensitive processing.
/**
* Convert string to lowercase
* @param str - Input string to normalize
* @returns Lowercase string
*/
function normalize(str: string): string;Usage Examples:
const xml2js = require('xml2js');
// Direct usage
const result = xml2js.processors.normalize('PRODUCT');
console.log(result); // 'product'
// In parser configuration
const options = {
tagNameProcessors: [xml2js.processors.normalize],
attrNameProcessors: [xml2js.processors.normalize]
};
const xmlString = '<PRODUCT ID="123"><NAME>Item</NAME></PRODUCT>';
xml2js.parseString(xmlString, options, (err, result) => {
if (!err) {
console.log(result); // Tags and attributes converted to lowercase
}
});Converts the first character of a string to lowercase, useful for camelCase conversion.
/**
* Convert first character to lowercase
* @param str - Input string to process
* @returns String with first character in lowercase
*/
function firstCharLowerCase(str: string): string;Usage Examples:
const xml2js = require('xml2js');
// Direct usage
console.log(xml2js.processors.firstCharLowerCase('ProductName')); // 'productName'
console.log(xml2js.processors.firstCharLowerCase('UserID')); // 'userID'
console.log(xml2js.processors.firstCharLowerCase('XMLParser')); // 'xMLParser'
// Convert XML tags to camelCase
const options = {
tagNameProcessors: [xml2js.processors.firstCharLowerCase],
explicitArray: false
};
const xmlString = `
<UserProfile>
<FirstName>John</FirstName>
<LastName>Doe</LastName>
<EmailAddress>john@example.com</EmailAddress>
</UserProfile>
`;
xml2js.parseString(xmlString, options, (err, result) => {
if (!err) {
console.log(result);
// Result will have camelCase property names:
// { userProfile: { firstName: 'John', lastName: 'Doe', emailAddress: 'john@example.com' } }
}
});Removes XML namespace prefixes from element and attribute names.
/**
* Remove XML namespace prefixes
* @param str - Input string that may contain namespace prefix
* @returns String with namespace prefix removed
*/
function stripPrefix(str: string): string;Usage Examples:
const xml2js = require('xml2js');
// Direct usage
console.log(xml2js.processors.stripPrefix('ns:ProductName')); // 'ProductName'
console.log(xml2js.processors.stripPrefix('soap:Envelope')); // 'Envelope'
console.log(xml2js.processors.stripPrefix('PlainElement')); // 'PlainElement' (no change)
// Strip namespaces during parsing
const options = {
tagNameProcessors: [xml2js.processors.stripPrefix],
attrNameProcessors: [xml2js.processors.stripPrefix],
explicitArray: false
};
const namespacedXml = `
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://example.com/webservice">
<soap:Header />
<soap:Body>
<web:GetUserRequest web:userId="123">
<web:UserName>John Doe</web:UserName>
</web:GetUserRequest>
</soap:Body>
</soap:Envelope>
`;
xml2js.parseString(namespacedXml, options, (err, result) => {
if (!err) {
console.log(result);
// Result will have namespace prefixes stripped:
// { Envelope: { Header: '', Body: { GetUserRequest: { UserName: 'John Doe' } } } }
}
});Converts numeric strings to JavaScript numbers when possible, leaving non-numeric strings unchanged.
/**
* Convert numeric strings to numbers
* @param str - Input string to parse
* @returns Number if string is numeric, original string otherwise
*/
function parseNumbers(str: string): string | number;Usage Examples:
const xml2js = require('xml2js');
// Direct usage
console.log(xml2js.processors.parseNumbers('42')); // 42 (number)
console.log(xml2js.processors.parseNumbers('3.14159')); // 3.14159 (number)
console.log(xml2js.processors.parseNumbers('-123')); // -123 (number)
console.log(xml2js.processors.parseNumbers('0')); // 0 (number)
console.log(xml2js.processors.parseNumbers('not a number')); // 'not a number' (string)
console.log(xml2js.processors.parseNumbers('')); // '' (string)
// Parse numbers in XML values
const options = {
valueProcessors: [xml2js.processors.parseNumbers],
explicitArray: false
};
const xmlWithNumbers = `
<product>
<id>12345</id>
<price>99.99</price>
<quantity>0</quantity>
<discount>-5.50</discount>
<name>Smartphone</name>
<active>true</active>
</product>
`;
xml2js.parseString(xmlWithNumbers, options, (err, result) => {
if (!err) {
console.log(result);
// Numbers are converted: { product: { id: 12345, price: 99.99, quantity: 0, discount: -5.5, name: 'Smartphone', active: 'true' } }
}
});Converts boolean string representations to JavaScript boolean values.
/**
* Convert boolean strings to booleans
* @param str - Input string to parse
* @returns Boolean if string represents true/false, original string otherwise
*/
function parseBooleans(str: string): string | boolean;Usage Examples:
const xml2js = require('xml2js');
// Direct usage
console.log(xml2js.processors.parseBooleans('true')); // true (boolean)
console.log(xml2js.processors.parseBooleans('false')); // false (boolean)
console.log(xml2js.processors.parseBooleans('TRUE')); // true (boolean) - case insensitive
console.log(xml2js.processors.parseBooleans('False')); // false (boolean)
console.log(xml2js.processors.parseBooleans('yes')); // 'yes' (string) - not converted
console.log(xml2js.processors.parseBooleans('1')); // '1' (string) - not converted
// Parse booleans in XML values
const options = {
valueProcessors: [xml2js.processors.parseBooleans],
attrValueProcessors: [xml2js.processors.parseBooleans],
explicitArray: false
};
const xmlWithBooleans = `
<settings>
<feature enabled="true">
<name>Auto-save</name>
<active>false</active>
<visible>TRUE</visible>
</feature>
<debug>False</debug>
</settings>
`;
xml2js.parseString(xmlWithBooleans, options, (err, result) => {
if (!err) {
console.log(result);
// Booleans are converted: enabled, active, visible, debug become boolean values
}
});Processors can be chained together in arrays to apply multiple transformations:
const xml2js = require('xml2js');
// Combine multiple processors
const advancedOptions = {
// Process tag names: strip namespaces, then convert to camelCase
tagNameProcessors: [
xml2js.processors.stripPrefix,
xml2js.processors.firstCharLowerCase
],
// Process attribute names: normalize to lowercase
attrNameProcessors: [
xml2js.processors.normalize
],
// Process values: parse numbers and booleans
valueProcessors: [
xml2js.processors.parseNumbers,
xml2js.processors.parseBooleans
],
// Process attribute values: parse numbers and booleans
attrValueProcessors: [
xml2js.processors.parseNumbers,
xml2js.processors.parseBooleans
],
explicitArray: false,
mergeAttrs: true
};
const complexXml = `
<ns:Product xmlns:ns="http://example.com/products" ID="123" Active="true">
<ns:ProductName>Laptop Computer</ns:ProductName>
<ns:Price Currency="USD">999.99</ns:Price>
<ns:InStock>5</ns:InStock>
<ns:Featured>false</ns:Featured>
</ns:Product>
`;
xml2js.parseString(complexXml, advancedOptions, (err, result) => {
if (!err) {
console.log(JSON.stringify(result, null, 2));
// Result combines all transformations:
// - Namespace prefixes removed
// - Tag names converted to camelCase
// - Attribute names normalized to lowercase
// - Numeric and boolean values properly typed
}
});You can create custom processor functions that follow the same pattern:
const xml2js = require('xml2js');
// Custom processor to convert snake_case to camelCase
function snakeToCamel(str) {
return str.replace(/_([a-z])/g, (match, letter) => letter.toUpperCase());
}
// Custom processor to convert units
function parseUnits(str) {
const match = str.match(/^(\d+(?:\.\d+)?)\s*(px|em|rem|%)$/);
if (match) {
return {
value: parseFloat(match[1]),
unit: match[2]
};
}
return str;
}
// Use custom processors
const customOptions = {
tagNameProcessors: [snakeToCamel],
valueProcessors: [parseUnits, xml2js.processors.parseNumbers],
explicitArray: false
};
const xmlWithCustomData = `
<css_style>
<font_size>16px</font_size>
<margin_top>2em</margin_top>
<opacity>0.8</opacity>
</css_style>
`;
xml2js.parseString(xmlWithCustomData, customOptions, (err, result) => {
if (!err) {
console.log(JSON.stringify(result, null, 2));
// Custom processors applied: snake_case -> camelCase, units parsed
}
});When multiple processors are specified in an array, they are applied in order from first to last:
const xml2js = require('xml2js');
// Order matters: first strip prefix, then convert case
const options1 = {
tagNameProcessors: [
xml2js.processors.stripPrefix, // First: 'ns:ProductName' -> 'ProductName'
xml2js.processors.firstCharLowerCase // Then: 'ProductName' -> 'productName'
]
};
// Different order produces different results
const options2 = {
tagNameProcessors: [
xml2js.processors.firstCharLowerCase, // First: 'ns:ProductName' -> 'ns:productName'
xml2js.processors.stripPrefix // Then: 'ns:productName' -> 'productName'
]
};
// Both produce the same final result in this case, but order can matter for complex transformationsInstall with Tessl CLI
npx tessl i tessl/npm-xml2js