Reputation: 425
I have a xml file whose content I need to read and convert into a json file. The content of the xml file should be copied as is and put into the json file.
This works mostly without any issues, if the xml file however contains strings such as <data key="foo">foo\nbar</data>
the generated json file will contain foo\\nbar
because the backslash is escaped.
I could iterate over the input string and replace all two char occurrences of \
and n
with a single \n
but then I have to do the same thing for \t
, \b
, \f
and so on.
Is there a way to prevent this and just stringifying the "raw" content?
My code to read and convert the xml file basically looks like this
const fs = require("fs");
const util = require("util");
const xml2js = require("xml2js");
const readFile = util.promisify(fs.readFile);
async function main() {
const fileContent = await readFile("data/test.xml");
const dataFields = (await xml2js.parseStringPromise(fileContent))["root"]["data"];
const result = dataFields.reduce((previous, current) => {
const key = current["$"].key;
const value = current["_"];
previous[key] = value;
return previous;
}, {});
console.log(JSON.stringify(result, null, 2));
}
main();
Example xml file:
<root>
<data key="foo">foo\nbar</data>
<data key="qux">qux\\nquux</data>
</root>
The actual output
{
"foo": "foo\\nbar",
"qux": "qux\\\\nquux"
}
although I want the desired output of
{
"foo": "foo\nbar",
"qux": "qux\\nquux"
}
Upvotes: 0
Views: 1856
Reputation: 1746
The whole point here is that everything is working as expected. The correct escaped string representation of text foo\nbar
actually is "foo\\nbar"
.
When you do console.log("foo\\nbar")
you get foo\nbar
printed to the console.
Now, what you actually want though is for the input text to be unescaped a linefeed.
So that this text:
foo\nbar
should become this text:
foo
bar
The escaped string representation of the latter being "foo\nbar"
There’s a package for that, and I’m applying it in the reduce
function.
const fs = require('fs')
const xml2js = require('xml2js')
const unescape = require('unescape-js')
async function main() {
const fileContent = fs.readFileSync('test.xml', 'utf-8')
const xml = await xml2js.parseStringPromise(fileContent)
const result = xml.root.data
.reduce((result, {_, $}) => ({
...result,
[$.key]: unescape(_)
}), {})
console.log(JSON.stringify(result, null, 2))
}
main()
Upvotes: 1