
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
xml-js-converter
Advanced tools
Convert XML to a JavaScript object and back, following a specific schema. Define your own rules for how to convert attributes and content
We use semver, and we're starting at 1.0.0 in order to easily communicate API changes, without breaking semver.
However, it's still beta and should be used with caution.
Convert between an XML string and JavaScript objects (in both directions), following a specific schema.
If you only need a generic conversion, you will probably find https://www.npmjs.com/package/xml2js or https://www.npmjs.com/package/xml2json suits your needs better.
What xml-js-converter allows you to do, is specify the way in which certain nodes are converted.
For instance, say you had the following XML:
<person id="195">
<firstName>Alan</firstName>
<lastName>Turing</lastName>
</person>
What you might want in JavaScript is
{
person: {
id: '195',
firstName: 'Alan',
lastName: 'Turing'
}
}
So the id attribute is a property, but so is the sub-element firstName. Converting back should obviously do the same thing, so from the given JavaScript object, you get the same XML back.
Say you had the following XML
<person id="195">
<firstName>Alan</firstName>
<lastName>Turing</lastName>
<skills>
<skill id="CS101">Computer theory</skill>
<skill id="ENIG1">Code breaking</skill>
</skills>
</person>
(The skills list is by no means exhaustive!)
What you can obtain with xml-js-converter is the following JavaScript object:
{
person: {
id: '195',
firstName: 'Alan',
lastName: 'Turing',
skills: [
{ skill: {
id: 'CS101',
name: 'Computer theory'
},
{ skill: {
id: 'ENIG1',
name: 'Code breaking'
}
]
}
}
Notice the extra "skill" object - ie. an object with a single property "skill". This is so that you can have an array of sub-elements with different tag names. For instance:
<person id="195">
<firstName>Alan</firstName>
<lastName>Turing</lastName>
<attributes>
<skill id="CS101">Computer theory</skill>
<achievement id="ENIG1">Cracked the Enigma code</achievement>
</attributes>
</person>
And end up with the JavaScript:
{
person: {
id: '195',
firstName: 'Alan',
lastName: 'Turing',
attributes: [
{ skill: {
id: 'CS101',
name: 'Computer theory'
},
{ achievement: {
id: 'ENIG1',
name: 'Code breaking'
}
]
}
}
npm install xml-js-converter
var xmlJsConverter = require('xml-js-converter');
fromXml(xmlAsString, specification, callback)
Where callback is function (err, value) { ... }, err is null unless there was an error,
and value is the javascript object. specification is defined in the next section.
xmlJsConverter.fromXml('<demo>text content</demo>', {}, function (err, value) {
// value == { demo: { $content: 'text content' } }
});
toXml(jsObject, specification, callback)
Where callback is function (err, value) { ... } , err is null unless there was an error,
and value is a string with the XML.
The specification can be an empty object. Otherwise each property can define how to handle that tag name.
For instance:
{
test: {}
}
Would be a (useless, ie. "non-effect having") specification for:
<test>some content</test>
This would result in
{
test: {
$content: 'some content'
}
}
$content is the default name for the content of a tag. You can override this in the spec by setting $content.
Set to a string to name the content property. e.g.
var spec = {
test: {
$content: 'name'
}
};
xmlJsConverter.fromXml('<test>charles babbage</test>', spec, function (err, value) {
// value == {
// test: {
// name: 'charles babbage'
// }
// };
});
Set to false to suppress the content. Note that attributes of the node will then be skipped,
as there is nowhere to define them.
e.g.
var spec = {
test: {
$content: false
}
};
xmlJsConverter.fromXml('<test>charles babbage</test>', spec, function (err, value) {
// value == {
// test: 'charles babbage'
// };
});
To define $content for deeply nested elements, simply define the path to the elements.
e.g.
var spec = {
test: {
name: {
firstName: { $content: false },
lastName: { $content: false }
}
}
};
xmlJsConverter.fromXml('<test><name>' +
'<firstName>charles</firstName>' +
'<lastName>babbage</lastName>' +
'</name></test>', spec, function (err, value) {
// value == {
// test: {
// name: {
// firstName: 'charles',
// lastName: 'babbage'
// }
// }
// };
});
Set to true to include the children as an array. Each child node will be an object with a single property with the name of the tag, and then follow the conventions of sub-schema.
Note that the array will be the $content property, unless $content is also specified (either set as a name or to false to discard the attributes).
From the example above:
<person id="195">
<firstName>Alan</firstName>
<lastName>Turing</lastName>
<attributes>
<skill id="CS101">Computer theory</skill>
<achievement id="ENIG1">Cracked the Enigma code</achievement>
</attributes>
</person>
To obtain the following JavaScript:
{
person: {
id: '195',
firstName: 'Alan',
lastName: 'Turing',
attributes: [
{ skill: {
id: 'CS101',
name: 'Computer theory'
},
{ achievement: {
id: 'ENIG1',
name: 'Code breaking'
}
]
}
}
You'd use the specification:
var spec = {
person: {
firstName: { $content: false },
lastName: { $content: false },
attributes: {
$arrayElement: true,
$content: false,
achievement: { $content: 'name' },
skill: { $content: 'name' }
}
}
};
Note how the $arrayElement is true, and also $content is false for the attributes element.
This suppresses the $content property for the array. $content for array elements works exactly
the same as normal elements.
The specs for achievement and skill will be used for every achievement and skill element
in the parent element. If an unknown element occurs, it will simply use a default specification ({})
Bugs, pull requests, comments all very welcome.
The tests are written in mocha, using the excellent unexpected assertion library.
To run the tests, just call
npm test
We follow semver. We have started at version 1.0, not symbolise "production ready", but to effectively communicate changes.
Things we'd like soon:
Things we'd like eventually:
Support for naming nodes differently in JS and XML
Support for dropping the wrapper on arrayElements e.g. from
<people>
<person name="monica" />
<person name="steve" />
</people>
To be transformed to
{ people: [ { name: 'monica' }, { name: 'steve' } ] }
<director>
<person name="tim cook" />
</director>
To be transformed to
{
director: {
person: 'tim cook'
}
}
This would also enable the people array in the previous example to be transformed to a simple array of strings.
FAQs
Convert XML to a JavaScript object and back, following a specific schema. Define your own rules for how to convert attributes and content
We found that xml-js-converter demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.