2015-02-24 1 views
4

Пытается разобрать XML в JSON с помощью xml2js, а затем вернуть JSON в XML с помощью xmlbuilder (обычно после изменения программного обеспечения программно).Разбирайте XML в JSON и обратно ... с xml2js и xmlbuilder?

I думаю, что два должны быть дополнениями, за это сообщение 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> 

Здесь, S, как 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:

  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> 

Так есть две проблемы, с которыми сталкивается XML-конструктор: * он не распознает имена атрибутов в объекте @ и * он не распознает значение атрибута внутри объект атрибута

Взлом оказывается, что xmlbuilder хочет атрибуты имен структурированы как:

`{ "@name": "Office Theme"} ` 

, а не

`{ "@" : { "name" : { value: "Office Theme" }}}` 

Должен ли я настроить xml2js по-разному, xmlbuilder по-разному, или есть другая пара библиотеки, которые могут анализировать XML -> JSON -> XML?

+1

Есть ли конкретная причина для этого объезда в JSON и обратно? Изменение XML напрямую кажется более разумным, когда XML - это то, что вы хотите иметь в конце ... – Tomalak

+0

Большой вопрос. В этом случае UI и DB работают с объектами JS/JSON, поэтому возможность представлять XML-контент (например, документ MS Office) в качестве JSON позволяет настраивать пользовательские конфигурации путем смешивания в объектах без явного пересечения DOM. Я надеялся, что задний конец будет таким же простым, как «xml2js.parseString (xml, function (err, json)» {_.mixin (json, edits); xmlbuilder.create (json) .end(); ' – prototype

ответ

11

xml2js package поставляется с собственным 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); 

В момент, один к одному двунаправленный преобразование гарантируется только для конфигурации по умолчанию, за исключением параметров 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); 
} 
+0

Спасибо! слепота, как-то с именем «xml2js», которое я пропустил, это также «js2xml». – prototype

+0

Я заметил, что комментарии XML отбрасываются при преобразовании из XML в JSON, но я полагаю, что ваш входной XML не содержит критически важных комментариев. ваш файл как UTF-8 (по умолчанию используется 'fs.writeFile()', но в любом случае сделать его явным в вашем коде, если бы он был симметричным с 'fs.readFile()'). См. измененный код. – Tomalak

0

Хотя Преобразование XML в JSON, The xml2js отображает атрибуты '$'. В случае, если ваше имя ключа не совпадает с именем дочернего ключа. Вы можете объединить атрибуты с элементами Child. Осторожно, ваш JSON выглядит чистым.

**

xml2js.Parser ({ignoreAttrs: ложные, mergeAttrs: истинный})

**

Может решить вашу проблему.

1

В последнее время я столкнулся с аналогичным требованием. Пришлось преобразовать данные xml службы погоды Yahoo в объект 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); 
.... 

вот ссылка Github для детального кода: https://github.com/joshiparthin/ReNode/tree/master/soap-api

 Смежные вопросы

  • Нет связанных вопросов^_^