Node.js JSON to XML - serialize a complex object - node.js

I'm attempting to convert a complex JSON object to XML using this package - XML.
var xml = require("xml");
var obj = { MS : { ts : 3423523, isOk : false , errors : [] }};
var xmlObj = xml(obj); // This outputs <MS/>
Any ideas how to make the XML parser go deeper? Why is it prematurely closed?

You could give the xml2js module a try, this would convert your object to Xml quite easily, e.g.
const xml2js = require('xml2js');
const obj = { MS : { ts : 3423523, isOk : false , errors : [] }};
const builder = new xml2js.Builder( { headless: false, renderOpts: { pretty: true } });
const xml = builder.buildObject(obj);
console.log(xml)
The output would be:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MS>
<ts>3423523</ts>
<isOk>false</isOk>
</MS>

Related

Reading JSON using Kotlin

I'd love to know what I'm doing wrong - can't access "links" on my JSON file.
Part of code (MainActivity.kt):
var arr = arrayListOf<String>()
fun read_json() {
var json : String? = null
try {
val inputStream:InputStream = assets.open("links.json")
json = inputStream.bufferedReader().use{it.readText()}
var jsonarr = JSONArray(json)
for (i in 0..jsonarr.length()-1){
var jsonobj = jsonarr.getJSONObject(i)
arr.add(jsonobj.getString("links"))
}
var adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, arr)
json_list.adapter = adapter
}
catch(e : IOException){
}
}
JSON file:
{
"links":
[
"google.com",
"youtube.com",
"facebook.com"
]
}
If I remake JSON file, so it will like in the following JSON file, everything works fine. However, I need to use the previous file. 😒
[
{
"links": "google.com"
}
]
Would really appreciate your help!
I believe you need to get the JSON array first and read strings from it, something like this:
var jsonarr = JSONObject(json).getJSONArray("links")
for (i in 0..jsonarr.length()-1) {
arr.add(jsonarr.getString(i))
}

NodeJS checking if XML element exists and add or delete

I'm working with XML in NodeJS. I've been using the xmlbuilder to create my XML. The problem is that now I need to check if a element already exists and delete or update it.
For example, I have the following XML
<?xml version="1.0"?>
<listings>
<listing>
<id>1</id>
<name>TEST</name>
<description>TEST</description>
</listing>
<listing>
<id>2</id>
<name>TEST</name>
<description>TEST</description>
</listing>
</listings>
Then, I call my updateXML controller to add data to it.
const builder = require('xmlbuilder');
const fs = require('fs');
const path = require("path");
exports.updateXML = async (req, res, next) => {
const data = req.body.data;
/*
For example data is
{
id: 2,
name: "Test2",
description: "Desc2"
}
*/
const xmlFile = fs.readFileSync(path.resolve(__dirname, "./oodle.xml"), 'utf8');
if(/*How do I check if the xmlFile has a <id> === data.id?*/) {
// If id matches. How can I delete the whole <listing> node for that id?
}
const newListing = builder.create('listing');
newListing.ele("id", data.id);
newListing.ele("name", data.name);
newListing.ele("description", data.description);
// How can I add the newListing node to the xmlFile?
}
Thanks
I don't believe it's really necessary to remove the node with the duplicate <id>, create a new <listing> node and then insert it into the xml. At least as far as the sample xml in your question is concerned, you can just modify the text child nodes of the relevant <listing> node.
Something along the lines of:
const { select } = require('xpath');
let query = `//listing[./id[./text()="${data.id}"]]`;
const nodes = select(query, doc.node);
nodes.forEach(function (node) {
nam = select('.//name/text()',node)
desc = select('.//description/text()',node)
nam[0].data = data.name;
desc[0].data = data.description;
});
const serializedXML = doc.end({ format: 'xml', prettyPrint: true });
console.log(serializedXML)
Output:
<?xml version="1.0"?>
<listings>
<listing>
<id>1</id>
<name>TEST</name>
<description>TEST</description>
</listing>
<listing>
<id>2</id>
<name>Test2</name>
<description>Desc2</description>
</listing>
</listings>

JSON to XML conversion in Node JS service (using xml2js)

I need some help/advice with JSON to XML conversion in Node js.
I have a service that gets a JSON object in request body that needs to convert to XML. I am able to achieve this using node-xml2js for json inputs with maximum one level of nested objects. But, it gets way more complicated with nested objects having attribute values. Attributes should be identified first, prefixed with $ sign and enclosed in curly braces before parsing through xml2js to get correct xml.
Is there a better way of doing this where this complicated layer of reformatting the json input can be simplified?
xml2js can converts this:
{
"Level1":{ "$":{ "attribute":"value" },
"Level2": {"$":{"attribute1":"05/29/2020",
"attribute2":"10","attribute3":"Pizza"}}
}
to this:(which is correct):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Level1 attribute="value">
<Level2 attribute1="05/29/2020" attribute2="10" attribute3="Pizza"/>
</Level1>
But actual json input is this:
{
"Level1":{"attribute":"value",
"Level2": {"attribute1":"05/29/2020",
"attribute2":"10","attribute3":"Pizza"} }
}
Expected same result:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Level1 attribute="value">
<Level2 attribute1="05/29/2020" attribute2="10" attribute3="Pizza"/>
</Level1>
Please let me know if you have worked on similar requirements. Appreciate any help.
Thank you.
This would be a way to change the object back to the format expected in the library, although it assumes that all non object keys are supposed to be attributes (is that a valid assumption for your application?)
function groupChildren(obj) {
for(prop in obj) { // consider filtering for own properties (vs from prototype: for(prop of Object.keys(obj)) {
if (typeof obj[prop] === 'object') {
groupChildren(obj[prop]);
} else {
obj['$'] = obj['$'] || {};
obj['$'][prop] = obj[prop];
delete obj[prop];
}
}
return obj;
}
and then used like so:
var xml2js = require('xml2js');
var obj = {
Level1: {
attribute: 'value',
Level2: {
attribute1: '05/29/2020',
attribute2: '10',
attribute3: 'Pizza'
}
}
};
var builder = new xml2js.Builder();
var xml = builder.buildObject(groupChildren(obj));
which prints out:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Level1 attribute="value">
<Level2 attribute1="05/29/2020" attribute2="10" attribute3="Pizza"/>
</Level1>
you can use this library :nashwaan/xml-js
Like This:
let xmlJ=require('xml-js');
let parseToJson=(xml)=>{
return new Promise(resolve => {
let convert;
convert=xmlJ.xml2json(xml,{compact:true});
resolve(convert);
});
};

Cannot access json values after converting from xml using xml-js parser

I parse the xml using the following code
var convert = require('xml-js');
var xml = require('fs').readFileSync('./2B2DE7DD-FD11-4F2C-AF0D-A244E5977CBA.xml', 'utf8');
result = convert.xml2json(xml, { spaces: 4});
The result throws the following JSON
{
"declaration": {
"attributes": {
"version": "1.0",
"encoding": "utf-8"
}
}
}
However if i try accesing "declaration" using result["declaration"]the console returns undefined
Should i use another parser or is there something wrong with getting the value.
Please use xml2js instead of xml2json if you want it return object.
result = convert.xml2js(xml, options); // to convert xml text to javascript object
result = convert.xml2json(xml, options); // to convert xml text to json text
The data type of result is String, not JavaScript object. That is, the convert.xml2json(xml, { spaces: 4}); statement will return a JSON String, not JS object.
To access declaration, you need to parse the JSON string to object:
var convert = require('xml-js');
var xml = require('fs').readFileSync('./2B2DE7DD-FD11-4F2C-AF0D-A244E5977CBA.xml', 'utf8');
result = convert.xml2json(xml, { spaces: 4});
result = JSON.parse(result);

Replacing tag content with html string

I have the following xml:
<foo><toReplace/></foo>
I want to replace <toReplace/> tag with the following string:
"<b>bar</b>"
How can I do that?
Right now I have the following code:
var xml = "<foo><toReplace/></foo>";
var parser = new dom.DOMParser().parseFromString(xml, "text/xml");
parser.getElementsByTagName("toReplacce")[0].textNode = "<b>bar</b>";
console.log(parser.toString()); // "<foo><b>bar</b>"
The problem is that is escapes HTML. How can I replace the content with the HTML string here?
you can always use the module from npm
var unescape = require('unescape');
console.log(unescape(parser.toString()))
When I tested your code there is a small typo: (toReplacce instead of toReplace)
var dom = require('xmldom');
var xml = "<foo><toReplace/></foo>";
var parser = new dom.DOMParser().parseFromString(xml, "text/xml");
var a = parser.getElementsByTagName("toReplace")[0];
//console.dir(a);
a.textvalue = "<b>bar</b>";
console.log(parser.toString());

Resources