将 XML 解析为 JSON 并返回……使用 xml2js 和 xmlbuilder?
Parse XML to JSON and back ... with xml2js and xmlbuilder?
尝试使用 xml2js and then return the JSON to XML using xmlbuilder 将 XML 解析为 JSON(通常在以编程方式修改内容之后)。
我 认为 根据这个 post https://github.com/oozcitak/xmlbuilder-js/issues/69,两者应该是互补的。但是我遇到了一些困难,这一定是我没有得到正确的配置参数。
这是我的代码 运行:
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})
});
这是原文的第一位 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>
这是 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"
},
...
注意上面的JSON:
- 属性(例如
name=
)在 @
对象和 中变成键
- 属性值变成对象
现在是 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>
所以 XML builder 面临两个问题:
* 它无法识别 @
对象中的属性名称,并且
* 它没有识别属性对象中的属性值
看来 xmlbuilder 希望属性名称的结构如下:
`{ "@name": "Office Theme"} `
而不是
`{ "@" : { "name" : { value: "Office Theme" }}}`
我应该以不同的方式配置 xml2js,以不同的方式配置 xmlbuilder,还是有一对不同的库可以解析 XML -> JSON -> XML?
xml2js package 带有自己的 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.
因此,在删除您的自定义解析器配置后,这对我来说非常有效:
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);
}
在将 XML 转换为 JSON 时,xml2js 将属性映射到“$”。如果您的属性键名称与子键名称不匹配。您可以将属性与子元素合并。因此,您的 JSON 看起来很干净。
**
xml2js.Parser({ignoreAttrs : false, mergeAttrs : true})
**
可能会解决您的问题。
我最近遇到了类似的需求。必须将 Yahoo 天气服务 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);
});
这之后就可以使用js2xmlparser将得到的json转换为xml。
js2xmlparser.parse("weather", data);
....
这里有一个Githublink的详细代码:https://github.com/joshiparthin/ReNode/tree/master/soap-api
尝试使用 xml2js and then return the JSON to XML using xmlbuilder 将 XML 解析为 JSON(通常在以编程方式修改内容之后)。
我 认为 根据这个 post https://github.com/oozcitak/xmlbuilder-js/issues/69,两者应该是互补的。但是我遇到了一些困难,这一定是我没有得到正确的配置参数。
这是我的代码 运行:
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})
});
这是原文的第一位 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>
这是 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"
},
...
注意上面的JSON:
- 属性(例如
name=
)在@
对象和 中变成键
- 属性值变成对象
现在是 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>
所以 XML builder 面临两个问题:
* 它无法识别 @
对象中的属性名称,并且
* 它没有识别属性对象中的属性值
看来 xmlbuilder 希望属性名称的结构如下:
`{ "@name": "Office Theme"} `
而不是
`{ "@" : { "name" : { value: "Office Theme" }}}`
我应该以不同的方式配置 xml2js,以不同的方式配置 xmlbuilder,还是有一对不同的库可以解析 XML -> JSON -> XML?
xml2js package 带有自己的 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.
因此,在删除您的自定义解析器配置后,这对我来说非常有效:
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);
}
在将 XML 转换为 JSON 时,xml2js 将属性映射到“$”。如果您的属性键名称与子键名称不匹配。您可以将属性与子元素合并。因此,您的 JSON 看起来很干净。
**
xml2js.Parser({ignoreAttrs : false, mergeAttrs : true})
**
可能会解决您的问题。
我最近遇到了类似的需求。必须将 Yahoo 天气服务 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);
});
这之后就可以使用js2xmlparser将得到的json转换为xml。
js2xmlparser.parse("weather", data);
....
这里有一个Githublink的详细代码:https://github.com/joshiparthin/ReNode/tree/master/soap-api