将XML解析为JSON并返回...使用xml2js和xmlbuilder?

pro*_*ype 6 xml-builder node.js xml-parsing

试图解析XML为JSON与xml2js,然后使用返回JSON来XML xmlbuilder(通常修改编程内容之后).

认为这两个应该是补充,按照这篇文章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})
});
Run Code Online (Sandbox Code Playgroud)

这是原始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>
Run Code Online (Sandbox Code Playgroud)

这里; 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"
                        },
                       ...
Run Code Online (Sandbox Code Playgroud)

请注意,在上面的JSON中:

  1. 属性(例如name=)被转换为@对象内的键
  2. 属性值转换为对象

现在,这是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>
Run Code Online (Sandbox Code Playgroud)

因此,XML构建器面临两个问题:*它不识别@对象中的属性名称,而*它不识别属性对象中的属性值

黑客攻击似乎xmlbuilder希望属性名称结构如下:

  `{ "@name": "Office Theme"} `
Run Code Online (Sandbox Code Playgroud)

而不是

  `{ "@" : { "name" : { value: "Office Theme" }}}`
Run Code Online (Sandbox Code Playgroud)

我应该以不同方式配置xml2js,xmlbuilder是不同的,还是有一对不同的库可以解析XML - > JSON - > XML?

Tom*_*lak 19

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);
Run Code Online (Sandbox Code Playgroud)

目前,只有默认配置才能保证一对一的双向转换,除了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);
}
Run Code Online (Sandbox Code Playgroud)