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");
      			}
      		}
      	}
      }