XML to JSON converter

Mar 12, 2012 at 5:44pm

XML to JSON converter

Has anyone written an XML to JSON converter Max object either in C, Java or JavaScript and is willing to share?

Thanks,

Georg

#62327
Mar 12, 2012 at 5:57pm

I have some JavaScript something that was written for Browsers. It’s not tested on Max (And in fact I don’t even know in as far the XML-Dom model in implemented in Max/JavaScript). But Maybe it can serve as a starting point.

Attributes are appended as NamedNodeMaps as ‘@’ and if an element has more than one child with the same TagName tey are parsed into an array (otherwise they stay objects…)

/**
		 * Parse an XmlNode recursivly into JSON
		 * TODO Test behavior if a node has siblings of the same NodeType and child-nodes
		 */
		var toJSON = function(xmlNode, jsonObject) {
			if(!xmlNode) return;
			jsonObject = jsonObject || {};
			if($(xmlNode).children().length >= 1 ){
				jsonObject[xmlNode.nodeName] = { '@' : xmlNode.attributes};
				$.each($(xmlNode).children(),function(index, childElement){
					toJSON(childElement, jsonObject[xmlNode.nodeName]);
				});
			} else {
				if(jsonObject[xmlNode.nodeName] == undefined) {
					jsonObject[xmlNode.nodeName] = {value : $(xmlNode).text(), '@' : xmlNode.attributes};
				} else {
					if($.isArray(jsonObject[xmlNode.nodeName])) {
						var nodeText = $(xmlNode).text();
						var nodeName = xmlNode.nodeName;
						jsonObject[xmlNode.nodeName].push({value : nodeText, '@' : xmlNode.attributes});
					} else {
						// Get existing Values
						var existingAttributes = jsonObject[xmlNode.nodeName]['@']
						var exitsingValue = jsonObject[xmlNode.nodeName]['value']
						var nodeText = $(xmlNode).text();
						jsonObject[xmlNode.nodeName] = [];
						jsonObject[xmlNode.nodeName].push({value : exitsingValue, '@' : existingAttributes});
						jsonObject[xmlNode.nodeName].push({value : nodeText, '@' : xmlNode.attributes});
					}
				}
			}
			return jsonObject;
		}
#225136
Mar 12, 2012 at 6:14pm

… just see that there is also some jQuery inside ($.isArray()) -> this won’t work for sure… so it’s probably really more an inspiration, than a solution ….

#225137
Mar 12, 2012 at 6:25pm

Thanks, there are a number of scripts out there. The questions is whether someone has actually succeeded in getting them to run inside Max.

#225138
Mar 12, 2012 at 6:32pm

I found this script, but I don’t know how to convert the jsonobject to text (my naive attempt to use the toString() method) failed miserably, and I also don’t know what to do with the last two ifs—they’re probably browser-related:

/*
xml2json v 1.1
copyright 2005-2007 Thomas Frank

This program is free software under the terms of the
GNU General Public License version 2 as published by the Free
Software Foundation. It is distributed without any warranty.
*/
autowatch = 1;

inlets = 1;
outlets = 1;

function input(myXML)
{
myJsonObject=xml2json.parser(myXML);
outlet(0,myJsonObject.toString());
post(myJsonObject);
post();
}

xml2json={
parser:function(xmlcode,ignoretags,debug){
if(!ignoretags){ignoretags=”"};
xmlcode=xmlcode.replace(/s*/>/g,’/>’);
xmlcode=xmlcode.replace(/< ?[^>]*>/g,”").replace(/< ![^>]*>/g,”");
if (!ignoretags.sort){ignoretags=ignoretags.split(“,”)};
var x=this.no_fast_endings(xmlcode);
x=this.attris_to_tags(x);
x=escape(x);
x=x.split(“%3C”).join(“< ").split("%3E").join(">“).split(“%3D”).join(“=”).split(“%22″).join(“”");
for (var i=0;i
x=x.replace(new RegExp(“< "+ignoretags[i]+">“,”g”),”*$**”+ignoretags[i]+”**$*”);
x=x.replace(new RegExp(““,”g”),”*$***”+ignoretags[i]+”**$*”)
};
x=’‘+x+’‘;
this.xmlobject={};
var y=this.xml_to_object(x).jsontagwrapper;
if(debug){y=this.show_json_structure(y,debug)};
return y
},
xml_to_object:function(xmlcode){
var x=xmlcode.replace(/
x=x.split(“< ");
var y=[];
var level=0;
var opentags=[];
for (var i=1;i
var tagname=x[i].split(“>”)[0];
opentags.push(tagname);
level++
y.push(level+”< "+x[i].split("§")[0]);
while(x[i].indexOf(“§”+opentags[opentags.length-1]+”>”)>=0){level–;opentags.pop()}
};
var oldniva=-1;
var objname=”this.xmlobject”;
for (var i=0;i
var preeval=”";
var niva=y[i].split(“< ")[0];
var tagnamn=y[i].split(“< ")[1].split(">“)[0];
tagnamn=tagnamn.toLowerCase();
var rest=y[i].split(“>”)[1];
if(niva< =oldniva){
var tabort=oldniva-niva+1;
for (var j=0;j
};
objname+=”.”+tagnamn;
var pobject=objname.substring(0,objname.lastIndexOf(“.”));
if (eval(“typeof “+pobject) != “object”){preeval+=pobject+”={value:”+pobject+”};n”};
var objlast=objname.substring(objname.lastIndexOf(“.”)+1);
var already=false;
for (k in eval(pobject)){if(k==objlast){already=true}};
var onlywhites=true;
for(var s=0;s
if(rest.charAt(s)!=”%”){onlywhites=false}
};
if (rest!=”" && !onlywhites){
if(rest/1!=rest){
rest=”‘”+rest.replace(/’/g,”\’”)+”‘”;
rest=rest.replace(/*$***/g,”
rest=rest.replace(/*$**/g,”< ");
rest=rest.replace(/**$*/g,”>”)
}
}
else {rest=”{}”};
if(rest.charAt(0)==”‘”){rest=’unescape(‘+rest+’)'};
if (already && !eval(objname+”.sort”)){preeval+=objname+”=["+objname+"];n”};
var before=”=”;after=”";
if (already){before=”.push(“;after=”)”};
var toeval=preeval+objname+before+rest+after;
eval(toeval);
if(eval(objname+”.sort”)){objname+=”["+eval(objname+".length-1")+"]“};
oldniva=niva
};
return this.xmlobject
},
show_json_structure:function(obj,debug,l){
var x=”;
if (obj.sort){x+=”[n"} else {x+="{n"};
for (var i in obj){
if (!obj.sort){x+=i+":"};
if (typeof obj[i] == “object”){
x+=this.show_json_structure(obj[i],false,1)
}
else {
if(typeof obj[i]==”function”){
var v=obj[i]+”";
//v=v.replace(/t/g,”");
x+=v
}
else if(typeof obj[i]!=”string”){x+=obj[i]+”,n”}
else {x+=”‘”+obj[i].replace(/’/g,”\’”).replace(/n/g,”\n”).replace(/t/g,”\t”).replace(/r/g,”\r”)+”‘,n”}
}
};
if (obj.sort){x+=”],n”} else {x+=”},n”};
if (!l){
x=x.substring(0,x.lastIndexOf(“,”));
x=x.replace(new RegExp(“,n}”,”g”),”n}”);
x=x.replace(new RegExp(“,n]”,”g”),”n]”);
var y=x.split(“n”);x=”";
var lvl=0;
for (var i=0;i
if(y[i].indexOf(“}”)>=0 || y[i].indexOf(“]”)>=0){lvl–};
tabs=”";for(var j=0;j
x+=tabs+y[i]+”n”;
if(y[i].indexOf(“{“)>=0 || y[i].indexOf(“[“)>=0){lvl++}
};
if(debug==”html”){
x=x.replace(//g,”>”);
x=x.replace(/n/g,”
“).replace(/t/g,”

#225139
Mar 12, 2012 at 11:26pm

Hi Georg,

There’s an XSL transformation which converts XMLs to JSON files, available on this site:

http://code.google.com/p/xml2json-xslt/

Then, with mxj quickie, one can create a very simple class which makes XSL transformations:

import com.cycling74.max.*;
import java.io.File;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;

public class xslt extends MaxObject
{
private Transformer transformer;
public xslt(Atom[] args) {
declareInlets(new int[]{DataTypes.ALL, DataTypes.ALL});
declareOutlets(new int[]{DataTypes.ALL});
setInletAssist(new String[]{“XML inlet”, “XSLT inlet”});
setOutletAssist(new String[]{“XML result”});
}
public void anything(String msg, Atom[] args) {
String source = msg;
for ( Atom a : args ) {
source += ” ” + a.toString ( );
}
if (getInlet()==0){
// Convert XML
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
transformer.transform(new StreamSource(new StringReader(source)), new StreamResult(outputStream));
} catch (Exception e) {
// This is BAD CODING, exceptions must always be managed better than here…
bail(“FLÖFF”);
}
outlet(0,outputStream.toString());
} else {
// Import XSLT
try {
transformer = TransformerFactory.newInstance().newTemplates(new StreamSource(new File(msg))).newTransformer();
} catch (Exception e) {
// Oh, no! Not again…
bail(“BOING”);
}
}
}
}

If you compile this class with mxj quickie, you’ll be able to transform any XML into any other format that can be transformed automatically by XSLT-s. For instance, you could translate score-partwise MusicXML files to score-timewise ones using the XSLT provided by the developers of MusicXML, or by using the XSLT of the mentioned website, you would also be able to transform an XML to a JSON file. See this very simple patch for an example:

– Pasted Max Patch, click to expand. –

Hope this helps,
Ádám

#225140
Mar 12, 2012 at 11:30pm

Hm… Interesting… I used the ‘pre’ tags, but the code is just flushed… :-( I try it again:

import com.cycling74.max.*;
import java.io.File;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;

public class xslt extends MaxObject
{
	private Transformer transformer;
	public xslt(Atom[] args) {
		declareInlets(new int[]{DataTypes.ALL, DataTypes.ALL});
		declareOutlets(new int[]{DataTypes.ALL});
		setInletAssist(new String[]{"XML inlet", "XSLT inlet"});
		setOutletAssist(new String[]{"XML result"});
	}
	public void anything(String msg, Atom[] args) {
		String source = msg;
		for ( Atom a : args ) {
			source += " " + a.toString ( );
		}
		if (getInlet()==0){
			// Convert XML
		    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			try {
			    transformer.transform(new StreamSource(new StringReader(source)), new StreamResult(outputStream));
			} catch (Exception e) {
				// This is BAD CODING, exceptions must always be managed better than here...
				bail("FLÖFF");
			}
		    outlet(0,outputStream.toString());
		} else {
			// Import XSLT
			try {
				transformer = TransformerFactory.newInstance().newTemplates(new StreamSource(new File(msg))).newTransformer();
			} catch (Exception e) {
				// Oh, no! Not again...
				bail("BOING");
			}
		}
	}
}
#225141

You must be logged in to reply to this topic.