xml2js:输出如何?

新手上路,请多包涵

我正在尝试使用 node.js 模块 xml2js

我的代码很简单:

 function testparse(pathname, callback) {
    var parser = require('xml2js').Parser(),
        util = require('util'),
        fs = require('fs'),
    fs.readFile(pathname, function (err, data) {
        parser.parseString(data, function(err, result) {
            console.log('Complete result:');
            console.log(util.inspect(result, {depth: null})); //Work
            console.log('Try to access element:');
            console.log(result.smil.body); //Work
            console.log(result.smil.body.update); //Undefined
        });
    });
}

我的 xml 文件如下:

 <?xml version="1.0"?>
<smil>
    <head/>
    <body>
        <update /*some field*//>
        <stream name="name"/>
        <playlist /*some field*/>
            <video /*some field*//>
            <video /*some field*//>
            <video /*some field*//>
        </playlist>
    </body>
</smil>

输出给我:

 Complete result:
{ smil:
    { head: [''],
      body:
        [ { update: [[Object]],
            stream: [[Object]],
            playlist: [[Object]] } ] } }
Try to access element:
[Object]
Undefined

我通过尝试成功访问了正文,但现在我卡住了,是否有模板或示例说明 xml2js 如何在某处输出解析的 xml?

原文由 DrakaSAN 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 452
2 个回答

对于那些想知道,xml2js 使用和滥用数组的人

对于我的文件,树将是:

 .result //Object
|_.head //Array
|_.body //Array
  |_.update //Array
  | |_.$ //Object
  |   |_.fields //Strings
  |
  |_.stream //Array
  | |_.$ //Object
  |   |_.fields //Strings
  |
  |_.playlist //Array
    |_.$ //Object
      |_.fields //Strings
      |
      |_.video //Array
        |_.$ //Object
          |_.fields //Strings

原文由 DrakaSAN 发布,翻译遵循 CC BY-SA 3.0 许可协议

长话短说

它比看起来更难。阅读 Open311 JSON 和 XML 转换 页面,了解其他 JSON 端表示的详细信息。所有“使用和滥用”数组、额外的对象层、名称未出现在原始 XML 中的成员,或三者兼而有之。

长答案

xml2js 有一项令人羡慕的任务:在事先不知道模式的情况下,以一种可以逆转的方式将 XML 转换为 JSON。乍一看似乎很明显:

 <name>Fred</name> → { name: "Fred" }
<chacha /> → { chacha: null }

到目前为止很容易,对吧?不过这个怎么样?

 <x><y>z</y><x>

删除人类友好的名称会导致面临的不确定性 xml2js 。起初,您可能认为这是很合理的:

 { x: { y: "z" } }

后来,您被这个 XML 文本绊倒并意识到您猜测的模式是错误的:

 <x><y>z</y><y>z2</y></x>

呃哦。也许我们应该使用数组。至少所有成员都有相同的标签:

 { x: [ "z", "z2" ] }

然而,这不可避免地证明是短视的:

 <x><y>z</y><y>z2</y><m>n</m>happy</x>

呃…

 { x: [ { y: "z" }, { y : "z2" }, { m: "n" }, "happy" ] }

… 然后有人用一些属性和 XML 命名空间来打磨你。

构建更简洁的输出模式的方法对您来说是显而易见的。您可以从标记和属性名称中推断出详细信息。你懂的。

图书馆不同意这种理解。

如果库不知道模式,它必须“使用和滥用”数组、额外的对象层、特殊属性名称,或者三者兼而有之。

唯一的选择是采用可变输出模式。正如我们在上面看到的那样,一开始它很简单,但您很快就会发现自己编写了大量条件代码。考虑如果具有相同标签名称的孩子被折叠到一个列表中会发生什么,但前提是有多个孩子:

 if (Array.isArray(x.y)) {
    processTheYChildren(x.y);
} else if (typeof(x.y) === 'object') {
    // only one child; construct an array on the fly because my converter didn't
    processTheYChildren([x.y]);
} else ...

原文由 Garth Kidd 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏