在 NodeJS 中解析响应 XML 数据
Parse response XML data in NodeJS
我有一个来自我的 NodeJS 请求的简单 Web response.body,它看起来像这样,我需要将 ProjectNr 和 Description 放在一个数组中 - 我尝试了一些解析器,但 none为我工作(DomParser 等)我只是不知道该怎么做,因为当我使用 .getElementbyName 或 .getElementbyTagname 并搜索“ProjectNr”时,我只是得到“undefined”作为答案。
请帮我。非常感谢!
<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>
您问题中发布的代码不是 well-formed 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"
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>
你可以像这样用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' ]
}
我有一个来自我的 NodeJS 请求的简单 Web response.body,它看起来像这样,我需要将 ProjectNr 和 Description 放在一个数组中 - 我尝试了一些解析器,但 none为我工作(DomParser 等)我只是不知道该怎么做,因为当我使用 .getElementbyName 或 .getElementbyTagname 并搜索“ProjectNr”时,我只是得到“undefined”作为答案。 请帮我。非常感谢!
<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>
您问题中发布的代码不是 well-formed 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"
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>
你可以像这样用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' ]
}