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.
CodePudding user response:
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);