-
-
Save olegp/642667 to your computer and use it in GitHub Desktop.
// One way converter from E4X XML to JSON | |
// 1) turns <body><item>1</item><item>2</item></body> into | |
// body: {item: ["1", "2"]} so that lists are easier to work with | |
// 2) turns things like: <body a="a">whatever</body> into | |
// body: {_a: "a", _: "whatever"} | |
// however <body>whatever</body> becomes simply body: "whatever | |
// - attributes specified by ignored are ignored | |
function E4XtoJSON(xml, ignored) { | |
var r, children = xml.*, attributes = xml.@*, length = children.length(); | |
if(length == 0) { | |
r = xml.toString(); | |
} else if(length == 1) { | |
var text = xml.text().toString(); | |
if(text) { | |
r = text; | |
} | |
} | |
if(r == undefined) { | |
r = {}; | |
for each (var child in children) { | |
var name = child.localName(); | |
var json = E4XtoJSON(child, ignored); | |
var value = r[name]; | |
if(value) { | |
if(value.length) { | |
value.push(json); | |
} else { | |
r[name] = [value, json] | |
} | |
} else { | |
r[name] = json; | |
} | |
} | |
} | |
if(attributes.length()) { | |
var a = {}, c = 0; | |
for each (var attribute in attributes) { | |
var name = attribute.localName(); | |
if(ignored && ignored.indexOf(name) == -1) { | |
a["_" + name] = attribute.toString(); | |
c ++; | |
} | |
} | |
if(c) { | |
if(r) a._ = r; | |
return a; | |
} | |
} | |
return r; | |
} | |
// test, requires ringo/ringojs and chl/wraps-tagsoup | |
var tagsoup = require("wraps/tagsoup"); | |
var data = tagsoup.parse("http://groups.google.com/group/ringojs/feed/atom_v1_0_msgs.xml"); | |
print(JSON.stringify(E4XtoJSON(data, ["type", "space", "xmlns", "html"]), null, ' ')); |
Line 13 changed to: var text = xml.toString();
Thank You.
For input <body><item>1</item><item>2</item></body>
It throws an error "Cannot find funtion push in object 1." the problem is when the element names are same and it trys to push to a text.
if(value.length) {
value.push(json);
} else {
r[name] = [value, json]
}
The fix is
if(value instanceof Array) {
value.push(json);
} else {
r[name] = [value, json]
}
thank you ...
Hi All,
I have tried the above code it's working partially in my case am expecting slite change needed
Please guide me the help to get the expected result.
2) turns things like: whatever into
// body: {_a: "a", _: "whatever"}
Actual Input:
<Book><id value="312480"/><Item> <Type><language value="English"/></Type></Item><Item> <Type><language value="France"/></Type></Item><Item> <Type><language value="German"/></Type></Item></Book>
Actual Output:
{"id":{"_value":"312480"},"Item":[{"Type":{"language":{"_value":"English"}}},{"Type":{"language":{"_value":"France"}}},{"Type":{"language":{"_value":"German"}}}]}
Expected Output:
{"id":"312480","Item":[{"Type":{"language":"English"}},{"Type":{"language":"France"}},{"Type":{"language":"German"}}]}
Hi All,
Please guide me to achieve the above result.
@ascii-mango
反向处理
function JsonToE4X (json, txml,ignored) {
var data ,xmllist;
if(json instanceof Array){
xmllist = new XMLList('<></>');
for (var j = 0;j < json.length; j++) {
xmllist += JsonToE4X (json[j],txml.copy(),ignored)
}
}else{
data = json;
}
if(txml == undefined) txml = new XML('');
for(var key in data){
if(ignored&&ignored.indexOf(key)!=-1)continue;
if ( data[key] instanceof Array) {
for (var i = 0;i < data[key].length; i++) {
if(data[key][i] instanceof Object){
txml.appendChild(<{key}/>);
JsonToE4X( data[key][i], txml[key][i],ignored);
}else{
txml.appendChild(<{key}>{data[key][i]}</{key}>);
}
}
}else if(data[key]instanceof Object){
if(key == ''){
JsonToE4X(data[key], txml,ignored);
}else{
//txml[key]='';
txml.appendChild(<{key}/>);
JsonToE4X(data[key],txml[key],ignored);
}
}else {
if(typeof(key)=='string'&& key.indexOf('')==0){
var attrib="@"+key.substr(1);
txml[attrib]=data[key];
}else{
txml.appendChild(<{key}/>);
txml[key]=data[key];
}
}
}
return xmllist != undefined?xmllist:txml;;
}
Hi, how can I avoid the generated "null"-values of CDATA-Tags?