我有简单和复杂的JSON数据,并使用JavaScript递归方法将其转换为XML,如下所示:
var json = [
{
"id": "42cfb980-4221-e97f-f85a-f5fcf4d37f02",
"name": "outer",
"value": "",
"attributes": {},
"subNodes": [
{
"id": "d0794639-5568-3728-11a4-676eb100b07a",
"name": "inner",
"value": "inner vlaue",
"attributes": {},
"subNodes": []
}
]
}
];
function prepareXmlOutput(appendTo, obj) {
var i, k, attributeString = '';
for (i in obj) {
if (obj[i].attributes.length > 0) {
for (k in obj[i].attributes) {
attributeString += ((obj[i].attributes[k].name != '') ? obj[i].attributes[k].name+'="'+obj[i].attributes[k].value+'"' : '') + ' ';
}
}
if (obj[i].subNodes.length < 1) {
if (obj[i].value == '') {
appendTo += '</' + obj[i].name + attributeString.replace(/~+$/,'') + '>';
} else {
appendTo += '<' + obj[i].name + attributeString.replace(/~+$/,'') + '>' +obj[i].value+ '</' + obj[i].name + '>';
}
} else {
appendTo += '<' + obj[i].name + attributeString.replace(/~+$/,'') + '>';
appendTo += prepareXmlOutput(appendTo, obj[i].subNodes);
appendTo += '</' + obj[i].name + '>';
}
}
return appendTo;
}
prepareXmlOutput('', json);
这使得xml非常精细但有一个问题。这是它给我的XML:
"<outer><outer><inner>inner vlaue</inner></outer>"
问题是,它重复了第一个节点。它为什么会这样?我尝试了很多用dev工具调试它,我发现光标在完成这个堆栈后直接转到return语句:
appendTo += prepareXmlOutput(appendTo, obj[i].subNodes);
答案 0 :(得分:0)
替换此行:
appendTo += prepareXmlOutput(appendTo, obj[i].subNodes);
用这个:
appendTo += prepareXmlOutput('', obj[i].subNodes);
因为它必须独立于累积的appendTo
创建子节点的XML字符串。然后使用+=
将结果(返回值)附加到它。在您的代码中,结果会附加两次(在函数内部附加到appendTo
,然后使用+=
返回已经附加的结果再次附加)。对于 N 的深度,外部元素重复 N + 1 次,第二个外部元素重复 N 次,...和所以直到内部元素不再重复。
您遇到的错误示例:将appendTo
'<outer>'
作为参数传递给函数调用,appendTo
在调用时附加到'<inner>'
结束它返回'<outer><inner>'
然后使用appendTo
追加到'<outer>'
的前一个值(+=
),现在appendTo
变为'<outer><outer><inner>'
}(外部元素重复2次,因为它已经传递给调用一次(下面一级))如果下面有N级,那么appendTo
将被传递给N次调用:
appendTo = '<outer>'
appendTo = '<outer><outer><inner>'
appendTo = '<outer><outer><outer><inner><inner>'
答案 1 :(得分:0)
只是为了一些变化;你不妨这样做;
var json = [
{
"id": "42cfb980-4221-e97f-f85a-f5fcf4d37f02",
"name": "outer",
"value": "",
"attributes": {},
"subNodes": [
{
"id": "d0794639-5568-3728-11a4-676eb100b07a",
"name": "in01",
"value": "inner value",
"attributes": {color:"red"},
"subNodes": [{
"id": "d0794639-5568-3728-11a4-676eb100b07a",
"name": "in02",
"value": "more inner value",
"attributes": {color:"blue"},
"subNodes": [{
"id": "d0794639-5568-3728-11a4-676eb100b07a",
"name": "in03",
"value": "most innest value",
"attributes": {color:"pink"},
"subNodes": []
}]
}]
},
{
"id": "d0794639-5568-3728-11a4-676eb100b07b",
"name": "in11",
"value": "another inner value",
"attributes": {color:"orange"},
"subNodes": [{
"id": "d0794639-5568-3728-11a4-676eb100b07a",
"name": "in12",
"value": "more inner value",
"attributes": {color:"brown"},
"subNodes": []
}]
}
]
}
],
parseXML = (a, r = "") => a.length ? parseXML(a.slice(1), r + Object.keys(a[0].attributes)
.reduce((s,k) => s + " " + k + "=\"" + a[0].attributes[k] + "\"", "<" + a[0].name)
+ ">"
+ a[0].value
+ parseXML(a[0].subNodes,"")
+ "</"
+ a[0].name
+ ">")
: r;
console.log(parseXML(json));