Parse response XML data in NodeJS

I have a simple Web response.body from my NodeJS request which is looking like this, and I need to put the ProjectNr and Description in an Array – I tried some parsers but none of them works for me (DomParser etc.) I just don’t know what to do, since when I use the .getElementbyName or .getElementbyTagname and search for “ProjectNr” I just get “undefined” as an answer.
Please help me. Thanks a lot!

<XYZNetWebService xmlns="http://abcdefs">
<XYZNetResponse Guid="asfdsafdsa23c6" 
LastAccess="2022-02-24" Report="Projects" Parameter="" status="200">
<Project>
    <ProjectNr>505</ProjectNr>
    <Description>Testproject</Description>
</Project>
<Project>
    <ProjectNr>123</ProjectNr>
    <Description>Project2</Description>
</Project>

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

you can transform with camaro like this

const { transform } = require('camaro')

async function main() {
    const xml = `
<XYZNetWebService xmlns="http://abcdefs">
<XYZNetResponse Guid="asfdsafdsa23c6" 
LastAccess="2022-02-24" Report="Projects" Parameter="" status="200">
<Project>
    <ProjectNr>505</ProjectNr>
    <Description>Testproject</Description>
</Project>
<Project>
    <ProjectNr>123</ProjectNr>
    <Description>Project2</Description>
</Project>
</XYZNetResponse>
</XYZNetWebService>
`

    const template = {
        projectNr: ['//Project', 'ProjectNr'],
        projectDesc: ['//Project', 'Description']
    }
    const output = await transform(xml, template)
    console.log(output);
}

main()

output

{
  projectNr: [ '505', '123' ],
  projectDesc: [ 'Testproject', 'Project2' ]
}

Method 2

The code posted in your question is not well-formed xml which is why DOMParser wasn’t working. But if your actual code is something like the below, the following should work:

let xmldoc = `<?xml version="1.0" encoding="UTF-8"?>
<root>
   <XYZNetWebService xmlns="http://abcdefs"/>
<XYZNetResponse Guid="asfdsafdsa23c6" LastAccess="2022-02-24" Report="Projects" Parameter="" status="200"/>
<Project>
    <ProjectNr>505</ProjectNr>
    <Description>Testproject</Description>
</Project>
<Project>
    <ProjectNr>123</ProjectNr>
    <Description>Project2</Description>
</Project>
</root>`;

const data = new DOMParser().parseFromString(xmldoc, 'text/xml');
let x = data.evaluate("//Project", data, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (let i = 0; i < x.snapshotLength; i++) {
  let tags = data.evaluate('.//*', x.snapshotItem(i), null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  for (let i = 0; i < tags.snapshotLength; i++) {
    console.log(tags.snapshotItem(i).textContent);
  }
}

Output would be

"505"
"Testproject"
"123"
"Project2"

Method 3

The XML seems to use a default namespace (xmlns="http://abcdefs"). This means that the node Project has to be read as {http://abcdefs}Project.

Here is set of namespace aware methods (with the suffix NS) that take the expected namespace as an argument.

Xpath expression need a resolver – and they don’t have a default namespace. The prefixes you’re using in the Xpath expression are separate from the XML source. Which makes sense because the XML is an external source and could change.

I am using nws in the following example. So //nws:Project can be read as //{http://abcdefs}Project

const output = document.querySelector('#demo');

const resolver = function(prefix) {
    const namespaces = {
        nws: 'http://abcdefs'
    }
    return namespaces[prefix || ''] || null;
}

const data = new DOMParser().parseFromString(getXMLString(), 'text/xml');
const projects = data.evaluate(
    "//nws:Project", data, resolver, XPathResult.ANY_TYPE, null
);
let project;
while (project = projects.iterateNext()) {
    
    const projectNr = data.evaluate(
        'string(nws:ProjectNr)', project, resolver, XPathResult.STRING_RESULT, null
    ).stringValue;
    const description = data.evaluate(
        'string(nws:Description)', project, resolver, XPathResult.STRING_RESULT, null
    ).stringValue;
    
    output 
        .appendChild(document.createElement('li'))
        .textContent = `${projectNr}: ${description}`;
}

function getXMLString() {
    return `<?xml version="1.0" encoding="UTF-8"?>
    <XYZNetWebService xmlns="http://abcdefs">
      <XYZNetResponse Guid="asfdsafdsa23c6" LastAccess="2022-02-24" Report="Projects" Parameter="" status="200">
        <Project>
          <ProjectNr>505</ProjectNr>
          <Description>Testproject</Description>
        </Project>
        <Project>
          <ProjectNr>123</ProjectNr>
          <Description>Project2</Description>
        </Project>
      </XYZNetResponse>
    </XYZNetWebService>`
};
<ul id="demo">

</ul>


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x