XML to JSON converter


    Mar 12 2012 | 5:44 pm
    Has anyone written an XML to JSON converter Max object either in C, Java or JavaScript and is willing to share?
    Thanks,
    Georg

    • Mar 12 2012 | 5:57 pm
      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;
      		}
      
    • Mar 12 2012 | 6:14 pm
      ... 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 ....
    • Mar 12 2012 | 6:25 pm
      Thanks, there are a number of scripts out there. The questions is whether someone has actually succeeded in getting them to run inside Max.
    • Mar 12 2012 | 6:32 pm
      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("%3D").join("=").split("%22").join("""); for (var i=0;i x=x.replace(new RegExp("","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+" 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(" var tagnamn=y[i].split("")[0]; tagnamn=tagnamn.toLowerCase(); var rest=y[i].split(">")[1]; if(niva 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,"
    • Mar 12 2012 | 11:26 pm
      Hi Georg,
      There's an XSL transformation which converts XMLs to JSON files, available on this site:
      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:
      Hope this helps, Ádám
    • Mar 12 2012 | 11:30 pm
      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");
      			}
      		}
      	}
      }