使用插件: fast-xml-parser
使用说明:https://www.npmjs.com/package/fast-xml-parser
json转xml
var Parser = require("fast-xml-parser").j2xParser;
//default options need not to set
var options = {
attributeNamePrefix : "@_",
attrNodeName: "@", //default is false
textNodeName : "#text",
ignoreAttributes : true,
cdataTagName: "__cdata", //default is false
cdataPositionChar: "\\c",
format: false,
indentBy: " ",
supressEmptyNode: false,
tagValueProcessor: a=> he.encode(a, { useNamedReferences: true}),// default is a=>a
attrValueProcessor: a=> he.encode(a, {isAttributeValue: isAttribute, useNamedReferences: true})// default is a=>a
};
// 注意此处要将options作为参数传过来,与xml转json时options传送位置不一样,此处是坑
var parser = new Parser(options);
var xml = parser.parse(json_or_js_obj);
xml转json
var parser = require('fast-xml-parser');
var he = require('he');
var options = {
attributeNamePrefix : "@_",
attrNodeName: "attr", //default is 'false'
textNodeName : "#text",
ignoreAttributes : true,
ignoreNameSpace : false,
allowBooleanAttributes : false,
parseNodeValue : true,
parseAttributeValue : false,
trimValues: true,
cdataTagName: "__cdata", //default is 'false'
cdataPositionChar: "\\c",
parseTrueNumberOnly: false,
arrayMode: false, //"strict"
attrValueProcessor: (val, attrName) => he.decode(val, {isAttributeValue: true}),//default is a=>a
tagValueProcessor : (val, tagName) => he.decode(val), //default is a=>a
stopNodes: ["parse-me-as-string"]
};
// 一定要注意此处options传参位置与json转xml不一致
if( parser.validate(xmlData) === true) { //optional (it'll return an object in case it's not valid)
var jsonObj = parser.parse(xmlData,options);
}
// Intermediate obj
var tObj = parser.getTraversalObj(xmlData,options);
var jsonObj = parser.convertToJson(tObj,options);
xml必备知识
坑一
实体引用
在 XML 中,一些字符拥有特殊的意义。
如果你把字符 “<” 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。
这样会产生 XML 错误:
<message>if salary < 1000 then</message>
为了避免这个错误,请用实体引用来代替 “<” 字符:
<message>if salary < 1000 then</message>
在 XML 中,有 5 个预定义的实体引用:
注释:在 XML 中,只有字符 “<” 和 “&” 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。
因此,在json转化xml前,先将数据进行处理,才能保证xml再转成json后不会出现问题
blobObj.model = blobObj.model.replace(/</g, '_<_').replace(/>/g, '_>_');
坑二
对于map数据类型,key的首位为数字时,会出现问题,因此,在每一项加一个字符,比如k,
const nodeStatus = {};
Object.keys( blobObj.config.nodeStatus).forEach(key => {
nodeStatus['k' + key] = blobObj.config.nodeStatus[key];
});
blobObj.config.nodeStatus = nodeStatus;
然后就可以进行json转化xml了
const parser = new Parser(options);
const result = parser.parse({ xml: blobObj });
console.log('result', result);
坑三
xml转json
根据json转xml的规则,同样的进行解析
const parser = require('fast-xml-parser');
const options = {
ignoreAttributes: false,
allowBooleanAttributes: true,
parseNodeValue: true,
parseAttributeValue: true
};
const str = blob.toString();
let result = parser.parse(str, options);
result = result.xml;
console.log(result.model);
result.model = result.model.replace(/_<_/g, '<').replace(/_>_/g, '>');
const nodeStatus = {};
Object.keys(result.onlineConfig.nodeStatus).forEach(key => {
const key2 = key.substring(1);
nodeStatus[key2] = result.onlineConfig.nodeStatus[key];
});
result.onlineConfig.nodeStatus = nodeStatus;
坑四
xml转json后,出现的问题
1、若数组中只有一个元素,会转成字符串
2、若对象是空的,会转成空字符串
因此,做以下特殊处理
if (typeof result.config.rootIds === 'string'){
const arr = [];
arr.push(result.config.rootIds);
result.config.rootIds = arr;
}
if (result.config && result.config.projectName) result.config.projectName = result.config.projectName.toString();
if (result.config && result.config.version) result.config.version = result.config.version.toString();
if (result.onlineConfig && result.onlineConfig.version) result.onlineConfig.version = result.onlineConfig.version.toString();
if (result.onlineConfig && result.onlineConfig.privileges) result.onlineConfig.privileges = {};
如果大家遇到了别的问题,可在评论区留言
学习交流群