surrz
surrz

Reputation: 425

Javascript - JSON Stringify raw string (no additional escapes)

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

Answers (1)

AndreasPizsa
AndreasPizsa

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

Related Questions