xml2js:输出如何?
我正在尝试使用node.js模块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
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})
感谢@rohittuthramergeAttrs: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!' } }