Let's say I have the following xml code
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<catalog>
<person>
<name>John</name>
<surname>Smith</surname>
</person>
<person>
<name>Abe</name>
<surname>Lincoln</surname>
</person>
<person>
<name>James</name>
<surname>Bond</surname>
</person>
</catalog>
And I want to add a new node, let's say the following:
<person>
<name>Tony</name>
<surname>Stark</surname>
</person>
How do I do this in node js? I mean I have a file (/routes/index.js in node js express, to be exact), and I want to be able to add/modify existing xml file. I've tried fs.writeFile(), but this writes a whole new file, and fs.appendFile() adds a header(?xml + encoding and stuff) and root nodes after the last node, so I can't insert it into the catalog node. I can't get rid of the xml declaration header either.
I've been using .builder() to do this, and it looked like this
router.post('/addnode', function (req, res) {
var obj = {name: "Tony", surname: "Stark"};
var fs = require('fs');
var xml2js = require('xml2js');
var builder = new xml2js.Builder();
var xml = builder.buildObject(obj);
fs.writeFile('public/test.xml', xml, function (err) {
if (err) throw err;
console.log('It\'s saved!');
});
});
Finally I want to get that data from a from addnode, so I won't create a var obj in this function.
Let's say I have the following xml code
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<catalog>
<person>
<name>John</name>
<surname>Smith</surname>
</person>
<person>
<name>Abe</name>
<surname>Lincoln</surname>
</person>
<person>
<name>James</name>
<surname>Bond</surname>
</person>
</catalog>
And I want to add a new node, let's say the following:
<person>
<name>Tony</name>
<surname>Stark</surname>
</person>
How do I do this in node js? I mean I have a file (/routes/index.js in node js express, to be exact), and I want to be able to add/modify existing xml file. I've tried fs.writeFile(), but this writes a whole new file, and fs.appendFile() adds a header(?xml + encoding and stuff) and root nodes after the last node, so I can't insert it into the catalog node. I can't get rid of the xml declaration header either.
I've been using .builder() to do this, and it looked like this
router.post('/addnode', function (req, res) {
var obj = {name: "Tony", surname: "Stark"};
var fs = require('fs');
var xml2js = require('xml2js');
var builder = new xml2js.Builder();
var xml = builder.buildObject(obj);
fs.writeFile('public/test.xml', xml, function (err) {
if (err) throw err;
console.log('It\'s saved!');
});
});
Finally I want to get that data from a from addnode, so I won't create a var obj in this function.
Share Improve this question edited Feb 4, 2020 at 7:19 ns16 1,5502 gold badges20 silver badges29 bronze badges asked Jul 7, 2015 at 21:55 bananeeekbananeeek 1931 gold badge4 silver badges14 bronze badges2 Answers
Reset to default 8You can use a third-party library like xml2js, xml-js or xml-parse.
Let's say you have data variable with your xml code:
let data = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<catalog>
<person>
<name>John</name>
<surname>Smith</surname>
</person>
<person>
<name>Abe</name>
<surname>Lincoln</surname>
</person>
<person>
<name>James</name>
<surname>Bond</surname>
</person>
</catalog>`;
- xml2js
const xml2js = require('xml2js');
xml2js.parseString(data, (err, result) => {
result.catalog.person.push({ name: 'Tony', surname: 'Stark' });
const builder = new xml2js.Builder();
data = builder.buildObject(result);
// write data to file
});
- xml-js
const convert = require('xml-js');
const result = convert.xml2js(data, { compact: true });
result.catalog.person.push({ name: { _text: 'Tony' }, surname: { _text: 'Stark' } });
data = convert.js2xml(result, { compact: true, spaces: 2 });
// write data to file
- xml-parse
const xml = require('xml-parse');
let result = xml.parse(data);
result.find(n => n.tagName === 'catalog').childNodes.push({
type: 'element',
tagName: 'person',
childNodes: [{
type: 'element',
tagName: 'name',
childNodes: [{
type: 'text',
text: 'Tony'
}]
}, {
type: 'element',
tagName: 'surname',
childNodes: [{
type: 'text',
text: 'Stark'
}]
}],
});
data = xml.stringify(result, 2);
// write data to file
Unless the files' sizes are unacceptable and you cannot read them as a whole, you can use xml2js and never work with XML.
By using it, you can read the file, convert it in an object which is far easier to manipulate, add your stuff there and then convert it back as XML and write the result again on the original file.
Looking at your example, you create a new object and append it to the the file. Instead, you should read the already existent data and modify them, then write everything back (do not append them) to the file. To do that, you have to use the Parser
object from xml2js
.