Reputation: 529
I am having the following issue :
BE is returning a JSON file that has keys
and values
but some values are in XML format. How can I turn them into JSON as well ?
It's the first time I am seeing this kind of structure. So any help would be appreciated. I am working on in a React environment.
[{
"price": 19,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"items": [
{
"size": "regular",
"coating": "none",
"amount": 8
},
{
"size": "regular",
"coating": "CBD",
"amount": 4
}
]
},
{
"price": 18,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"items": "<items><item><size>regular</size><coating>none</coating><amount>10</amount></item><item><size>regular</size><coating>CBD</coating><amount>2</amount></item></items>"
},
{
"price": 19,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"items": [
{
"size": "small",
"coating": "none",
"amount": 8
},
{
"size": "small",
"coating": "CBD",
"amount": 4
}
]
},
{
"price": 18,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"items": "<items><item><size>small</size><coating>none</coating><amount>10</amount></item><item><size>small</size><coating>CBD</coating><amount>2</amount></item></items>"
},
{
"price": 17,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"items": "<items><item><size>regular</size><coating>none</coating><amount>12</amount></item></items>"
},
{
"price": 17,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"items": "<items><item><size>small</size><coating>none</coating><amount>12</amount></item></items>"
}]
Upvotes: 1
Views: 267
Reputation: 27192
Ideally it should be corrected at backend
itself but still if you don't have a control on backend and want to parse it in frontend only. You can simply achieve this requirement with the help of DOMParser
API.
Live Demo :
const inputArr = [{
"price": 19,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"items": [
{
"size": "regular",
"coating": "none",
"amount": 8
},
{
"size": "regular",
"coating": "CBD",
"amount": 4
}
]
}, {
"price": 18,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"items": "<items><item><size>regular</size><coating>none</coating><amount>10</amount></item><item><size>regular</size><coating>CBD</coating><amount>2</amount></item></items>"
}, {
"price": 19,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"items": [
{
"size": "small",
"coating": "none",
"amount": 8
},
{
"size": "small",
"coating": "CBD",
"amount": 4
}
]
}, {
"price": 18,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"items": "<items><item><size>small</size><coating>none</coating><amount>10</amount></item><item><size>small</size><coating>CBD</coating><amount>2</amount></item></items>"
}, {
"price": 17,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"items": "<items><item><size>regular</size><coating>none</coating><amount>12</amount></item></items>"
}, {
"price": 17,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"items": "<items><item><size>small</size><coating>none</coating><amount>12</amount></item></items>"
}];
const itemKeys = ['size', 'coating', 'amount'];
function parseXMLString(arr, itemKeys) {
const parser = new DOMParser();
arr.forEach((o, index) => {
const a = [];
if (typeof o.items === 'string') {
const xmlParsedStr = parser.parseFromString(o.items, "text/xml");
itemKeys.forEach(item => {
const itemKeysArr = xmlParsedStr.getElementsByTagName(item);
for (let i=0; i < itemKeysArr.length; i++) {
for (let j=0; j < itemKeysArr[i].childNodes.length; j++) {
a[i] ? a[i][item] = itemKeysArr[i].childNodes[j].nodeValue :
a[i] = { [item]: itemKeysArr[i].childNodes[j].nodeValue }
}
}
})
arr[index].items = a;
}
});
return arr;
}
console.log(parseXMLString(inputArr, itemKeys));
Upvotes: 2
Reputation: 188
Using https://www.npmjs.com/package/xml-js makes this a easy task
const convert = require('xml-js');
function convertItems(item) {
if (typeof item.items === 'string') {
const options = {compact: true, ignoreComment: true, spaces: 4};
const result = convert.xml2json(item.items, options);
const itemDetails = JSON.parse(result);
item["details"] = itemDetails.items.item;
delete item.items;
} else {
item["details"] = item.items;
delete item.items;
}
return false;
}
for (let i = 0; i < data.length; i++) {
convertItems(data[i]);
}
console.log(JSON.stringify(data, null, 4));
output:
[
{
"price": 19,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"details": [
{
"size": "regular",
"coating": "none",
"amount": 8
},
{
"size": "regular",
"coating": "CBD",
"amount": 4
}
]
},
{
"price": 18,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"details": [
{
"size": {
"_text": "regular"
},
"coating": {
"_text": "none"
},
"amount": {
"_text": "10"
}
},
{
"size": {
"_text": "regular"
},
"coating": {
"_text": "CBD"
},
"amount": {
"_text": "2"
}
}
]
},
{
"price": 19,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"details": [
{
"size": "small",
"coating": "none",
"amount": 8
},
{
"size": "small",
"coating": "CBD",
"amount": 4
}
]
},
{
"price": 18,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"details": [
{
"size": {
"_text": "small"
},
"coating": {
"_text": "none"
},
"amount": {
"_text": "10"
}
},
{
"size": {
"_text": "small"
},
"coating": {
"_text": "CBD"
},
"amount": {
"_text": "2"
}
}
]
},
{
"price": 17,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"details": {
"size": {
"_text": "regular"
},
"coating": {
"_text": "none"
},
"amount": {
"_text": "12"
}
}
},
{
"price": 17,
"currency": "GBP",
"productImage": "https://daye.cdn.prismic.io/daye/ee153f6163435330b18495535217c531300382a8_product2x.png",
"details": {
"size": {
"_text": "small"
},
"coating": {
"_text": "none"
},
"amount": {
"_text": "12"
}
}
}
]
Upvotes: 2