xml2js を使用してXMLをJSONに解析し、 xmlbuilder を使用してJSONをXMLに戻そうとしています(通常はプログラムでコンテンツを変更した後)。
私thinkこの投稿によると、2つは補完する必要があります 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ビルダーが直面している2つの問題があります。* @
オブジェクト内の属性名を認識しないことと*属性オブジェクト内の属性値を認識しないことです。
ハッキングすると、xmlbuilderは次のような構造の属性名を必要としているようです。
`{ "@name": "Office Theme"} `
のではなく
`{ "@" : { "name" : { value: "Office Theme" }}}`
Xml2jsを別の方法で構成する必要がありますか、xmlbuilderを別の方法で構成する必要がありますか、それともXML-> JSON-> XMLを解析できる別のライブラリのペアがありますか?
xml2jsパッケージ には独自のXMLビルダーが付属しており、ドキュメントには次のように記載されています。
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);
現時点では、1対1の双方向変換は、好みに合わせて再定義できるattrkey、charkey、explicitArrayオプションを除いて、デフォルト構成でのみ保証されています。
したがって、カスタムパーサー構成を削除した後、これは私にとって完全に機能します。
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);
}
最近、同様の要件に遭遇しました。 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);
});
この後、取得したjsonをxmlに変換するために js2xmlparser を使用できます。
js2xmlparser.parse("weather", data);
....
詳細なコードのGithubリンクは次のとおりです。 https://github.com/joshiparthin/ReNode/tree/master/soap-api
XMLをJSONに変換する際、xml2jsは属性を「$」にマップします。属性キー名が子キー名と一致しない場合。属性を子要素とマージできます。 JSONがきれいに見えるので。
****
xml2js.Parser({ignoreAttrs:false、mergeAttrs:true})
****
あなたの問題を解決するかもしれません。