Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
xml2js:输出如何?_Xml_Node.js_Xml Parsing - Fatal编程技术网

xml2js:输出如何?

xml2js:输出如何?,xml,node.js,xml-parsing,Xml,Node.js,Xml Parsing,我正在尝试使用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.parseSt

我正在尝试使用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>

通过尝试,我成功地访问了body,但现在我陷入了困境,是否有一个模板或示例说明xml2js如何在某处输出解析后的xml?

对于那些想知道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
有一项不令人羡慕的任务:以一种可以逆转的方式将XML转换为JSON,而无需事先知道模式。一开始似乎很明显:

<name>Fred</name> → { name: "Fred" }
<chacha /> → { chacha: null }
稍后,您会被这个XML文本绊倒,并意识到您对模式的猜测是错误的:

<x><y>z</y><y>z2</y></x>
然而,这不可避免地被证明是短视的:

<x><y>z</y><y>z2</y><m>n</m>happy</x>
。。。然后有人用一些属性和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 ...
TL;医生:比看起来难。阅读Open311页面了解其他JSON端表示的详细信息。所有“使用和滥用”数组、额外的对象层、名称未出现在原始XML中的成员,或者全部三个

As,您可以通过将属性
explicitArray
设置为
false
(重要提示:它必须是一个布尔值,因为字符串
“false”
只能不起作用!)

例如:

var parser = new xml2js.Parser({explicitArray : false});

这样,您应该能够以更简单的方式访问JSON属性。我希望这对任何人都有帮助。

返回的JSON对JavaScript不太友好。我已经编写了一个助手函数,可以使它更容易使用

在使用之前一定要阅读它,这样你才能理解它的作用

xml.parseString(xmlString, function(err, results){
    if(err) throw err

    results = cleanXML(results);
});

var cleanXML = function(xml){
    var keys = Object.keys(xml),
        o = 0, k = keys.length,
        node, value, singulars,
        l = -1, i = -1, s = -1, e = -1,
        isInt = /^-?\s*\d+$/,
        isDig = /^(-?\s*\d*\.?\d*)$/,
        radix = 10;

    for(; o < k; ++o){
        node = keys[o];

        if(xml[node] instanceof Array && xml[node].length === 1){
            xml[node] = xml[node][0];
        }

        if(xml[node] instanceof Object){
            value = Object.keys(xml[node]);

            if(value.length === 1){
                l = node.length;

                singulars = [
                    node.substring(0, l - 1),
                    node.substring(0, l - 3) + 'y'
                ];

                i = singulars.indexOf(value[0]);

                if(i !== -1){
                    xml[node] = xml[node][singulars[i]];
                }
            }
        }

        if(typeof(xml[node]) === 'object'){
            xml[node] = cleanXML(xml[node]);
        }

        if(typeof(xml[node]) === 'string'){
            value = xml[node].trim();

            if(value.match(isDig)){
                if(value.match(isInt)){
                    if(Math.abs(parseInt(value, radix)) <= Number.MAX_SAFE_INTEGER){
                        xml[node] = parseInt(value, radix);
                    }
                }else{
                    l = value.length;

                    if(l <= 15){
                        xml[node] = parseFloat(value);
                    }else{
                        for(i = 0, s = -1, e = -1; i < l && e - s <= 15; ++i){
                            if(value.charAt(i) > 0){
                                if(s === -1){
                                    s = i;
                                }else{
                                    e = i;
                                }
                            }
                        }

                        if(e - s <= 15){
                            xml[node] = parseFloat(value);
                        }
                    }
                }
            }
        }
    }

    return xml;
};
变成

{
  queries: [ {}, {}, {} ]
}
{
  types: [ {}, {}, {} ]
}

变成

{
  queries: [ {}, {}, {} ]
}
{
  types: [ {}, {}, {} ]
}
它还将安全地转换整数/浮点


编辑:替换为。。。对于我来说,这是一个console.dir问题,或者更准确地说是一个非问题

在输入console.dir输出时,我得到了相同的结果:

{
 TextView: [ [Object] ],
 ImageView: [ [Object] ] } }
但我惊讶地发现,这是一个console.dir限制,数据实际上就在那里。显然,console.dir只显示几个级别。当I console.dir进入更深层次时,数据就在那里:

 console.log(result.RelativeLayout.TextView);
输出:

 { '$':
 { 'android:layout_width': 'wrap_content',
   'android:layout_height': 'wrap_content',
   'android:layout_marginLeft': '10dp',
   'android:layout_marginTop': '10dp',
   'android:textColor': '#ffffff',
   'android:id': '@+id/textView',
   'android:text': 'Hello World!' } }

我开始寻找其他LIB,只是为了回去再试一次。如果它对任何人都有帮助的话,万岁。

你可能想尝试一下
控制台.log(util.inspect(result,false,null))
,它应该会显示整个结果。

回答得很好,即使是在以后的某个月。你放TL的时候是不是在跟我捣乱;最后的博士:)…更好的是,它实际上回答了这个问题。我没有提供模板或示例。:)如果您使用它,那么现在必须检查您是否实际收到了元素或元素数组。否则,您的代码中可能会出现类型灾难。我使用过它,然后它就会工作:
var Parser=require('xml2js-Parser')var Parser=new Parser({explicitArray:false,mergeAttrs:true})
感谢@rohittuthra
mergeAttrs:true
,为编辑@BhargavRao保存了我的邮箱,这让我更高兴,因为这是一个答案。
{
  types: { type: [ {}, {}, {} ] }
}
{
  types: [ {}, {}, {} ]
}
{
 TextView: [ [Object] ],
 ImageView: [ [Object] ] } }
 console.log(result.RelativeLayout.TextView);
 { '$':
 { 'android:layout_width': 'wrap_content',
   'android:layout_height': 'wrap_content',
   'android:layout_marginLeft': '10dp',
   'android:layout_marginTop': '10dp',
   'android:textColor': '#ffffff',
   'android:id': '@+id/textView',
   'android:text': 'Hello World!' } }