Handling XLM Input

by Nivaldo

HTML

<MTTR>
  <MONTH>
    <FixMonth>2012-12</FixMonth>
    <AvgMTTR>31.4700000</AvgMTTR>
    <DefectCaseCount>200</DefectCaseCount>
  </MONTH>
  <MONTH>
    <FixMonth>2013-01</FixMonth>
    <AvgMTTR>38.2764976</AvgMTTR>
    <DefectCaseCount>217</DefectCaseCount>
  </MONTH>
  <MONTH>
    <FixMonth>2013-02</FixMonth>
    <AvgMTTR>28.5416666</AvgMTTR>
    <DefectCaseCount>192</DefectCaseCount>
  </MONTH>
  <MONTH>
    <FixMonth>2013-03</FixMonth>
    <AvgMTTR>27.8351254</AvgMTTR>
    <DefectCaseCount>279</DefectCaseCount>
  </MONTH>
  <MONTH>
    <FixMonth>2013-04</FixMonth>
    <AvgMTTR>27.2445141</AvgMTTR>
    <DefectCaseCount>319</DefectCaseCount>
  </MONTH>
  <MONTH>
    <FixMonth>2013-05</FixMonth>
    <AvgMTTR>26.2034632</AvgMTTR>
   <DefectCaseCount>231</DefectCaseCount>
  </MONTH>
  <MONTH>
    <FixMonth>2013-06</FixMonth>
    <AvgMTTR>32.1470588</AvgMTTR>
    <DefectCaseCount>238</DefectCaseCount>
  </MONTH>
  <MONTH>
    <FixMonth>2013-07</FixMonth>
    <AvgMTTR>29.6721311</AvgMTTR>
    <DefectCaseCount>244</DefectCaseCount>
  </MONTH>
  <MONTH>
    <FixMonth>2013-08</FixMonth>
    <AvgMTTR>29.3853211</AvgMTTR>
    <DefectCaseCount>218</DefectCaseCount>
  </MONTH>
  <MONTH>
    <FixMonth>2013-09</FixMonth>
    <AvgMTTR>28.6966824</AvgMTTR>
    <DefectCaseCount>211</DefectCaseCount>
  </MONTH>
  <MONTH>
    <FixMonth>2013-10</FixMonth>
    <AvgMTTR>28.6500000</AvgMTTR>
    <DefectCaseCount>220</DefectCaseCount>
  </MONTH>
  <MONTH>
    <FixMonth>2013-11</FixMonth>
    <AvgMTTR>29.3197969</AvgMTTR>
    <DefectCaseCount>197</DefectCaseCount>
  </MONTH>
</MTTR>

CSS

MONTH, FixMonth, AvgMTTR, DefectCaseCount {
    display:block;
    padding:0 1em;
}
MONTH {
   border: 1px solid gray;
}

JavaScript

var dataset;

/* 
d3.xml("MTTR.xml", "application/xml", function(error, data) {
*/
function getData() {
    error = null;
    data = document.createDocumentFragment();
    data.appendChild(d3.select("MTTR").node()); 
//this is just a fiddle work-around to give the same result as the
//d3.xml function

    if (error) { return console.warn(error); }

   console.log(data);
//should give the same result as if you were using d3.xml

  dataset = xmlToJSON(data);      

  console.log(dataset);
  d3.select("body").text(JSON.stringify(dataset));

} //end of getData()
//}); //end of d3.xml()

//a recursive function to convert simple xml to JSON
//tag names become object keys
//elements with the same tag are grouped into arrays
//tag attributes are ignored
var nestByTagName = d3.nest().key(function(d){
        return d.tagName;
    });
function xmlToJSON(xml) {
    if (xml.children.length) {
        var o = {}
        var childTypes = nestByTagName.entries(xml.children);
        
        childTypes.forEach(function(type) {
            //each type, as returned by the nest function
            //will be an object with type.key = tagName
            //and type.values = array of xml child objects
            
            if (type.values.length == 1) {
                //only one child of this type
               o[type.key] =  xmlToJSON(type.values[0]);
            }
            else { // multiple children of this type
                o[type.key] = type.values.map( function(v) {
                        return xmlToJSON(v);
                    });
                //replace each xml object in the nested array
                //with its JSON-ified version
            }
            
        });
        return o;
    }
    else { //leaf node, return string value
        return xml.textContent;
    }

}
                
window.setTimeout(getData, 3000);