在 NodeJS 中解析响应 XML 数据

发布于 2025-01-09 16:31:51 字数 667 浏览 0 评论 0原文

我的 NodeJS 请求中有一个简单的 Web response.body,如下所示,我需要将 ProjectNr 和 Description 放入一个数组中 - 我尝试了一些解析器,但它们都不适合我(DomParser 等)我只是不知道不知道该怎么做,因为当我使用 .getElementbyName 或 .getElementbyTagname 并搜索“ProjectNr”时,我只是得到“未定义”作为答案。 请帮我。多谢!

<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>

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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南汐寒笙箫 2025-01-16 16:31:51

你可以用 camaro 像这样的

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()

输出进行转换

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

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' ]
}
浮云落日 2025-01-16 16:31:51

您问题中发布的代码不是格式良好的 xml,这就是 DOMParser 无法工作的原因。但是,如果您的实际代码如下所示,则以下内容应该有效:

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);
  }
}

输出将是

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

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"
墨落成白 2025-01-16 16:31:51

XML 似乎使用默认名称空间 (xmlns="http://abcdefs")。这意味着节点 Project 必须被读取为 {http://abcdefs}Project

这是一组命名空间感知方法(带有后缀 NS),它们将预期的命名空间作为参数。

Xpath 表达式需要解析器 - 并且它们没有默认名称空间。您在 Xpath 表达式中使用的前缀与 XML 源是分开的。这是有道理的,因为 XML 是外部源并且可能会发生变化。

我在以下示例中使用 nws。因此 //nws:Project 可以读作 //{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>

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>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文