NewInTown
NewInTown

Reputation: 529

How to convert items that are returned as an XML string rather than JSON?

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

Answers (2)

Roh&#236;t J&#237;ndal
Roh&#236;t J&#237;ndal

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

Alex Mortez
Alex Mortez

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

Related Questions