Search code examples
reactjsnext.jsxml-to-json

Error in parsing xml Response in react (nextjs)


I am working on a personal project and thought I would make a rest API that responds in json and xml both, everything on the json side works but when I get a response in xml. Everything fails and I get this error on console when I get the response and parsing it throws undefined.

Error

XML Parsing Error: junk after document element
Location: http://localhost:9000/xml/
Line Number 2, Column 1: xml:2:1

Parsed response

Object { message: "Success" }
​
message: "Success"
​
<prototype>: Object { … }

XML Response from the API

<message>Success</message>
<result>
    <filmID>82396e66-116f-4cb6-b3c9-918fc8bbcd5c</filmID>
    <title>Thor: Ragnork</title>
    <director>Chris Dave</director>
    <released>2020</released>
    <stars>5</stars>
    <review>Lala</review>
    <img>https://i.ytimg.com/vi/v7MGUNV8MxU/maxresdefault.jpg</img>
    <createdAt>2022-07-17T07:10:31</createdAt>
    <updatedAt>2022-07-22T15:34:10</updatedAt>
</result>
<result>
    <filmID>4ef55054-2ec9-4610-8b79-da296939d3d3</filmID>
    <title>Thor: Love and Thunder</title>
    <director>Chris Shake</director>
    <released>2022</released>
    <stars>3.5</stars>
    <review>Okayish Movie</review>
    <img>https://cdn.theatlantic.com/thumbor/JW6HNa00mCHyTJv9OoV9GeHBlyE=/1x0:2220x1248/960x540/media/img/mt/2022/07/MCDTHLO_WD024/original.jpg</img>
    <createdAt>2022-07-25T12:58:50</createdAt>
    <updatedAt>2022-07-25T13:00:49</updatedAt>
</result>

I have tried libraries like xml-to-json. How do I parse this, any help is appreciated.


Solution

  • What you've shown is not valid XML because there are multiple top-level nodes (they lack a common parent/root node).

    However, if you are expecting this format, then you don't necessarily need a library: implementing your own custom parser is relatively straightforward using DOMParser.parseFromString():

    See also: Parsing and serializing XML - Developer guides | MDN

    'use strict';
    
    function parse (rawText) {
      const parser = new DOMParser();
      const doc = parser.parseFromString(`<root>${rawText}</root>`, 'text/xml');
      const data = {};
    
      const message = doc.querySelector('root > message')?.textContent;
      if (message) data.message = message;
    
      for (const resultNode of doc.querySelectorAll('root > result')) {
        const result = {};
        for (const childNode of resultNode.children) {
          const text = childNode.textContent;
          if (text) result[childNode.tagName] = text;
        }
        (data.results ??= []).push(result);
      }
    
      return data;
    }
    
    const rawResponseText = `<message>Success</message>
    <result>
        <filmID>82396e66-116f-4cb6-b3c9-918fc8bbcd5c</filmID>
        <title>Thor: Ragnork</title>
        <director>Chris Dave</director>
        <released>2020</released>
        <stars>5</stars>
        <review>Lala</review>
        <img>https://i.ytimg.com/vi/v7MGUNV8MxU/maxresdefault.jpg</img>
        <createdAt>2022-07-17T07:10:31</createdAt>
        <updatedAt>2022-07-22T15:34:10</updatedAt>
    </result>
    <result>
        <filmID>4ef55054-2ec9-4610-8b79-da296939d3d3</filmID>
        <title>Thor: Love and Thunder</title>
        <director>Chris Shake</director>
        <released>2022</released>
        <stars>3.5</stars>
        <review>Okayish Movie</review>
        <img>https://cdn.theatlantic.com/thumbor/JW6HNa00mCHyTJv9OoV9GeHBlyE=/1x0:2220x1248/960x540/media/img/mt/2022/07/MCDTHLO_WD024/original.jpg</img>
        <createdAt>2022-07-25T12:58:50</createdAt>
        <updatedAt>2022-07-25T13:00:49</updatedAt>
    </result>`;
    
    const result = parse(rawResponseText);
    console.log(result);