Skip to content

Instantly share code, notes, and snippets.

@olegp
Created October 23, 2010 20:36
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save olegp/642667 to your computer and use it in GitHub Desktop.
Save olegp/642667 to your computer and use it in GitHub Desktop.
one way converter from E4X XML to JSON
// 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, ' '));
@kredmer
Copy link

kredmer commented May 2, 2013

Hi, how can I avoid the generated "null"-values of CDATA-Tags?

@kredmer
Copy link

kredmer commented May 3, 2013

Line 13 changed to: var text = xml.toString();

@splinter
Copy link

splinter commented Sep 4, 2013

Thank You.

@ascii-mango
Copy link

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]
}

@ahmedmostafam
Copy link

thank you ...

@nkn786
Copy link

nkn786 commented Apr 19, 2018

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"}}]}

@nkn786
Copy link

nkn786 commented Apr 25, 2018

Hi All,

Please guide me to achieve the above result.
@ascii-mango

@zhengdongyang
Copy link

zhengdongyang commented Sep 16, 2020

反向处理
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;;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment