title: Drawing a collapsible indented tree with d3.xml instead of d3.json
body: <p>I am able to get the collapsible indented tree to work properly with a JSON sample file; however, I cannot modify the code to use an XML file. Below are my sample JSON file, sample XML file, and attempt to modify .js file to use XML instead of JSON.</p>
  
  <p>I think that these are the key areas of code that I have to modify but not sure:</p>
  
  <pre><code>d3.xml("d3/simple-flare.xml", "application/xml", function (error, flare) {
          flare.x0 = 0;
          flare.y0 = 0;
          update(root = flare);
      });
  
  ...
  
  function update(source) {
  
          // Compute the flattened node list. TODO use d3.layout.hierarchy.
          var nodes = tree.nodes(root);
  
  ...
  
  // Update the links…
          var link = svg.selectAll("path.link")
              .data(tree.links(nodes), function (d) { return d.target.id; });
  </code></pre>
  
  <p>simple-flare.json</p>
  
  <pre><code>{
   "name": "flare",
   "children": [
    {
     "name": "analytics",
     "children": [
      {
       "name": "cluster",
       "children": [
        {"name": "AgglomerativeCluster", "size": 3938},
        {"name": "CommunityStructure", "size": 3812},
        {"name": "MergeEdge", "size": 743}
       ]
      },
      {
       "name": "graph",
       "children": [
        {"name": "BetweennessCentrality", "size": 3534},
        {"name": "LinkDistance", "size": 5731}
       ]
      },
      {
       "name": "optimization",
       "children": [
        {"name": "AspectRatioBanker", "size": 7074}
       ]
      }
     ]
    },
    {
     "name": "animate",
     "children": [
      {"name": "Easing", "size": 17010},
      {"name": "FunctionSequence", "size": 5842},
      {
       "name": "interpolate",
       "children": [
        {"name": "ArrayInterpolator", "size": 1983},
        {"name": "ColorInterpolator", "size": 2047},
        {"name": "DateInterpolator", "size": 1375},
        {"name": "Interpolator", "size": 8746},
        {"name": "MatrixInterpolator", "size": 2202},
        {"name": "NumberInterpolator", "size": 1382},
        {"name": "ObjectInterpolator", "size": 1629},
        {"name": "PointInterpolator", "size": 1675},
        {"name": "RectangleInterpolator", "size": 2042}
       ]
      },
      {"name": "ISchedulable", "size": 1041},
      {"name": "Parallel", "size": 5176},
      {"name": "Pause", "size": 449},
      {"name": "Scheduler", "size": 5593},
      {"name": "Sequence", "size": 5534},
      {"name": "Transition", "size": 9201},
      {"name": "Transitioner", "size": 19975},
      {"name": "TransitionEvent", "size": 1116},
      {"name": "Tween", "size": 6006}
     ]
    }
   ]
  }
  </code></pre>
  
  <p>simple-flare.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
  &lt;flare&gt;
    &lt;analytics&gt;
       &lt;cluster&gt;
          &lt;agglomerativeCluster&gt;3938&lt;/agglomerativeCluster&gt;
          &lt;communityStructure&gt;3812&lt;/communityStructure&gt;
          &lt;mergeEdge&gt;743&lt;/mergeEdge&gt;
       &lt;/cluster&gt;
       &lt;graph&gt;
          &lt;test&gt;3343&lt;/test&gt;
          &lt;mmmm&gt;3353&lt;/mmmm&gt;
          &lt;lalala&gt;454&lt;/lalala&gt;
       &lt;/graph&gt;
       &lt;optimization&gt;
          &lt;AspectRatio&gt;7074&lt;/AspectRatio&gt;
       &lt;/optimization&gt;
    &lt;/analytics&gt;
  &lt;/flare&gt;
  </code></pre>
  
  <p>collapseIndentTree.js</p>
  
  <pre><code>// Changes XML to JSON
  function xmlToJson(xml) {
  
      // Create the return object
      var obj = {};
  
      if (xml.nodeType == 1) { // element
          // do attributes
          if (xml.attributes.length &gt; 0) {
              obj["@attributes"] = {};
              for (var j = 0; j &lt; xml.attributes.length; j++) {
                  var attribute = xml.attributes.item(j);
                  obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
              }
          }
      } else if (xml.nodeType == 3) { // text
          obj = xml.nodeValue;
      }
  
      // do children
      if (xml.hasChildNodes()) {
          for (var i = 0; i &lt; xml.childNodes.length; i++) {
              var item = xml.childNodes.item(i);
              var nodeName = item.nodeName;
              if (typeof (obj[nodeName]) == "undefined") {
                  obj[nodeName] = xmlToJson(item);
              } else {
                  if (typeof (obj[nodeName].push) == "undefined") {
                      var old = obj[nodeName];
                      obj[nodeName] = [];
                      obj[nodeName].push(old);
                  }
                  obj[nodeName].push(xmlToJson(item));
              }
          }
      }
      return obj;
  };
  
  function indenttree() {
      var margin = { top: 30, right: 20, bottom: 30, left: 20 },
      width = 960 - margin.left - margin.right,
      barHeight = 20,
      barWidth = width * .8;
  
      var i = 0,
          duration = 400,
          root;
  
      var tree = d3.layout.tree()
          .nodeSize([0, 20]);
  
      var diagonal = d3.svg.diagonal()
          .projection(function (d) { return [d.y, d.x]; });
  
      var svg = d3.select(".nester_wrap").append("svg")
          .attr("width", width + margin.left + margin.right)
        .append("g")
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  
      d3.xml("d3/simple-flare.xml", "application/xml", function (error, flare) {
          var flareJSON = xmlToJson(flare)
          flareJSON.x0 = 0;
          flareJSON.y0 = 0;
  
          var xmlText = new XMLSerializer().serializeToString(flare);
          var xmlTextNode = document.createTextNode(xmlText);
          var parentDiv = document.getElementById('footerArea');
          parentDiv.appendChild(xmlTextNode);
  
          alert(JSON.stringify(flareJSON));
  
          update(root = flare);
          //update(root = flareJSON);
          //update(root = d3.select(flare).selectAll("*")[0]);
          //update(root = flare.selectNodes("//*")[0]);
      });
  
      /*
      d3.json("d3/simple-flare.json", function (error, flare) {
          flare.x0 = 0;
          flare.y0 = 0;
          update(root = flare);
      });
  
      //notes
      d3.json("flare.json", function(root) {
      var nodes = flatten(root),
          links = d3.layout.tree().links(nodes);
  
      d3.xml("flare.xml", "application/xml", function(xml) {
          var nodes = self.nodes = d3.select(xml).selectAll("*")[0],
              links = self.links = nodes.slice(1).map(function(d) {
                  return {source: d, target: d.parentNode};
              });
      */
  
      function update(source) {
  
          // Compute the flattened node list. TODO use d3.layout.hierarchy.
          var nodes = tree.nodes(root);
  
          var height = Math.max(500, nodes.length * barHeight + margin.top + margin.bottom);
  
          d3.select("svg").transition()
              .duration(duration)
              .attr("height", height);
  
          d3.select(self.frameElement).transition()
              .duration(duration)
              .style("height", height + "px");
  
          // Compute the "layout".
          nodes.forEach(function (n, i) {
              n.x = i * barHeight;
          });
  
          // Update the nodes…
          var node = svg.selectAll("g.node")
              .data(nodes, function (d) { return d.id || (d.id = ++i); });
  
          var nodeEnter = node.enter().append("g")
              .attr("class", "node")
              .attr("transform", function (d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
              .style("opacity", 1e-6);
  
          // Enter any new nodes at the parent's previous position.
          nodeEnter.append("rect")
              .attr("class", "indent")
              .attr("y", -barHeight / 2)
              .attr("height", barHeight)
              .attr("width", barWidth)
              .style("fill", color)
              .on("click", click);
  
          nodeEnter.append("text")
              .attr("class", "indent")
              .attr("dy", 3.5)
              .attr("dx", 5.5)
              .text(function (d) { return d.name; });
  
          // Transition nodes to their new position.
          nodeEnter.transition()
              .duration(duration)
              .attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; })
              .style("opacity", 1);
  
          node.transition()
              .duration(duration)
              .attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; })
              .style("opacity", 1)
            .select("rect")
              .style("fill", color);
  
          // Transition exiting nodes to the parent's new position.
          node.exit().transition()
              .duration(duration)
              .attr("transform", function (d) { return "translate(" + source.y + "," + source.x + ")"; })
              .style("opacity", 1e-6)
              .remove();
  
          // Update the links…
          var link = svg.selectAll("path.link")
              .data(tree.links(nodes), function (d) { return d.target.id; });
  
          // Enter any new links at the parent's previous position.
          link.enter().insert("path", "g")
              .attr("class", "link")
              .attr("d", function (d) {
                  var o = { x: source.x0, y: source.y0 };
                  return diagonal({ source: o, target: o });
              })
            .transition()
              .duration(duration)
              .attr("d", diagonal);
  
          // Transition links to their new position.
          link.transition()
              .duration(duration)
              .attr("d", diagonal);
  
          // Transition exiting nodes to the parent's new position.
          link.exit().transition()
              .duration(duration)
              .attr("d", function (d) {
                  var o = { x: source.x, y: source.y };
                  return diagonal({ source: o, target: o });
              })
              .remove();
  
          // Stash the old positions for transition.
          nodes.forEach(function (d) {
              d.x0 = d.x;
              d.y0 = d.y;
          });
      }
  
      // Toggle children on click.
      function click(d) {
          if (d.children) {
              d._children = d.children;
              d.children = null;
          } else {
              d.children = d._children;
              d._children = null;
          }
          update(d);
      }
  
      function color(d) {
          return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
      }
  }
  var chart = indenttree();
  </code></pre>