node.js 使用 xml2js 和 xmlbuilder 将 XML 解析为 JSON 并返回?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28688452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Parse XML to JSON and back ... with xml2js and xmlbuilder?
提问by prototype
Trying to parse XML into JSON with xml2jsand then return the JSON to XML using xmlbuilder(usually after modifying the content programmatically).
试图解析XML为JSON与xml2js,然后使用返回JSON来XML xmlbuilder(通常修改编程内容之后)。
I thinkthat the two should be complements, per this post https://github.com/oozcitak/xmlbuilder-js/issues/69. But am having some difficulty, and it's gotta be that I'm not getting the config parameters right.
我认为这两者应该是互补的,根据这篇文章https://github.com/oozcitak/xmlbuilder-js/issues/69。但是我遇到了一些困难,一定是我没有正确设置配置参数。
Here's the code I'm running:
这是我正在运行的代码:
var xml = fs.readFileSync(__dirname + '/../xml/theme.xml', 'utf8');
xml2js.parseString(xml, { attrkey: '@', xmlns: true }, function(err, json) {
var xml2 = xmlbuilder.create(json,
{version: '1.0', encoding: 'UTF-8', standalone: true}
).end({pretty: true, standalone: true})
});
Here's the first bit of the original XML:
这是原始 XML 的第一部分:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">
<a:themeElements>
<a:clrScheme name="Office">
<a:dk1>
<a:sysClr val="windowText" lastClr="000000"/>
</a:dk1>
<a:lt1>
<a:sysClr val="window" lastClr="FFFFFF"/>
</a:lt1>
<a:dk2>
<a:srgbClr val="1F497D"/>
</a:dk2>
...
</a:themeElements>
</a:theme>
Here;s how xml2js parses that to JSON, this looks right to me:
这里是 xml2js 如何将其解析为 JSON,这对我来说是正确的:
{
"a:theme": {
"@": {
"xmlns:a": {
"name": "xmlns:a",
"value": "http://schemas.openxmlformats.org/drawingml/2006/main",
"prefix": "xmlns",
"local": "a",
"uri": "http://www.w3.org/2000/xmlns/"
},
"name": {
"name": "name",
"value": "Office Theme",
"prefix": "",
"local": "name",
"uri": ""
}
},
"@ns": {
"uri": "http://schemas.openxmlformats.org/drawingml/2006/main",
"local": "theme"
},
"a:themeElements": [
{
"@ns": {
"uri": "http://schemas.openxmlformats.org/drawingml/2006/main",
"local": "themeElements"
},
"a:clrScheme": [
{
"@": {
"name": {
"name": "name",
"value": "Office",
"prefix": "",
"local": "name",
"uri": ""
}
},
"@ns": {
"uri": "http://schemas.openxmlformats.org/drawingml/2006/main",
"local": "clrScheme"
},
...
Note that in the JSON above:
请注意,在上面的 JSON 中:
- the attribute (e.g.
name=) are turned into keys inside an@object and - the attribute values are turned into objects
- 属性(例如
name=)被转换为@对象内的键,并且 - 属性值转化为对象
Now here's how it looks when xmlbuilder turns it back into XML:
现在这里是 xmlbuilder 将它转换回 XML 时的样子:
<a:theme ="[object Object]" ns="[object Object]">
<a:themeElements ns="[object Object]">
<a:clrScheme ="[object Object]" ns="[object Object]">
<a:dk1 ns="[object Object]">
<a:sysClr ="[object Object]" ns="[object Object]"/>
</a:dk1>
<a:lt1 ns="[object Object]">
<a:sysClr ="[object Object]" ns="[object Object]"/>
</a:lt1>
...
</a:themeElements>
</a:theme>
So there are two problems that XML builder is facing:
* it's not recognizing the attribute names within the @object and
* it's not recognizing the attribute value within the attribute object
因此,XML builder 面临两个问题: * 无法识别@对象中的属性名称; * 无法识别属性对象中的属性值
Hacking it appears that xmlbuilder wants attributes names structured like:
黑客似乎 xmlbuilder 想要结构化的属性名称,如:
`{ "@name": "Office Theme"} `
rather than
而不是
`{ "@" : { "name" : { value: "Office Theme" }}}`
Should I configure xml2js differently, xmlbuilder differently, or is there a different pair of libraries that can parse XML -> JSON -> XML?
我应该以不同的方式配置 xml2js,以不同的方式配置 xmlbuilder,还是有一对不同的库可以解析 XML -> JSON -> XML?
回答by Tomalak
The xml2js packagecomes with its own XML builder, to which the documentation has to say:
该xml2js包本身自带的XML构建,到文档不得不说:
Since 0.4.0, objects can be also be used to build XML:
var fs = require('fs'), xml2js = require('xml2js'); var obj = {name: "Super", Surname: "Man", age: 23}; var builder = new xml2js.Builder(); var xml = builder.buildObject(obj);At the moment, a one to one bi-directional conversion is guaranteed only for default configuration, except for attrkey, charkey and explicitArray options you can redefine to your taste.
从 0.4.0 开始,对象也可用于构建 XML:
var fs = require('fs'), xml2js = require('xml2js'); var obj = {name: "Super", Surname: "Man", age: 23}; var builder = new xml2js.Builder(); var xml = builder.buildObject(obj);目前,只有默认配置才能保证一对一的双向转换,除了您可以根据自己的喜好重新定义的 attrkey、charkey 和 explicitArray 选项。
So, after dropping your custom parser configuration, this works perfectly for me:
因此,在删除自定义解析器配置后,这对我来说非常有效:
var fs = require('fs');
var path = require('path');
var xml2js = require('xml2js');
xmlFileToJs('theme.xml', function (err, obj) {
if (err) throw (err);
jsToXmlFile('theme2.xml', obj, function (err) {
if (err) console.log(err);
})
});
// -----------------------------------------------------------------------
function xmlFileToJs(filename, cb) {
var filepath = path.normalize(path.join(__dirname, filename));
fs.readFile(filepath, 'utf8', function (err, xmlStr) {
if (err) throw (err);
xml2js.parseString(xmlStr, {}, cb);
});
}
function jsToXmlFile(filename, obj, cb) {
var filepath = path.normalize(path.join(__dirname, filename));
var builder = new xml2js.Builder();
var xml = builder.buildObject(obj);
fs.writeFile(filepath, xml, cb);
}
回答by Sumanth
While Converting XML to JSON , The xml2js maps the attributes to '$'. In case if your attributes key Name does not match with the Child Key Name . You could Merge the Attributes with Child elements . HEnce your JSON looks clean.
在将 XML 转换为 JSON 时,xml2js 将属性映射到“$”。如果您的属性键 Name 与 Child Key Name 不匹配。您可以将属性与子元素合并。因此您的 JSON 看起来很干净。
**
**
xml2js.Parser({ignoreAttrs : false, mergeAttrs : true})
xml2js.Parser({ignoreAttrs: false, mergeAttrs: true})
**
**
Might Solve your problem.
可能会解决您的问题。
回答by Parth Joshi
I came across similar requirement recently. Had to convert Yahoo weather service xml data into json object. Solved the issue with xml2js and js2xmlparser modules. Thought to share how I did here. An example which I worked out:
我最近遇到了类似的要求。必须将雅虎天气服务 xml 数据转换为 json 对象。解决了 xml2js 和 js2xmlparser 模块的问题。想分享我在这里的表现。我制定的一个例子:
const https = require('https');
var parseString = require('xml2js').parseString;
https.get('https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22surat%22)&format=xml&env=store%3A%2F%2F datatables.org%2Falltableswithkeys', (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
//console.log(JSON.parse(data).explanation);
parseString(data, function (err, result) {
console.log(JSON.stringify(result));
});
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
After this one can use js2xmlparserfor converting the obtained json to xml.
之后就可以使用js2xmlparser将得到的json转换成xml了。
js2xmlparser.parse("weather", data);
....
here's a Github link for the detailed code: https://github.com/joshiparthin/ReNode/tree/master/soap-api
这是详细代码的 Github 链接:https: //github.com/joshiparthin/ReNode/tree/master/soap-api

