It’s pretty quick-and-dirty, but this is my first attempt.

 

function xmlToHash(el) {

  Element.cleanWhitespace(el);

  if (el.hasAttributes() || (el.hasChildNodes() && el.childNodes[0].nodeType == 1)) {

    var localHash = {};

    if (el.hasAttributes && el.attributes.length >= 1) {

      $A(el.attributes).each(function (attr) { localHash[attr.nodeName] = attr.nodeValue; });

    }

    $A(el.childNodes).each(function (el) { xmlToHashElement(localHash, el); });

    for (attr in localHash) {

      if (localHash[attr].length == 1) {

        localHash[attr] = localHash[attr][0];

      }

    }

    return localHash;

  }

  else {

    return el.textContent || '';

  }

}

 

function xmlToHashElement (hash, el) {

  if (el.nodeType == 2) {

    hash[el.localName] = [ el.textContent ];

  }

  else {

              var key = el.tagName;

              if (hash[key]) {

                hash[key].push(xmlToHash(el));

              }

              else {

                hash[key] = [ xmlToHash(el) ];

              }

  }

}

 

You just do:

 

var hash = xmlToHash(response.responseXML.documentElement);

 

The tag name of the child nodes become the keys in the hash, and if there are more than one with the same tag name, it is an array as the value.  It handles attributes as well, with the attribute name becoming the hash key and the value the value.  I imagine if you had a child node with a tag name that matched the attribute, it would overwrite the attribute.  I didn’t think that was worth handling, as I couldn’t think of a legitimate scenario where it would be desirable.

 

And it’s recursive, so you can put nodes within nodes and it will create hashes out of them.  I imagine it doesn’t handle every possible scenario, but it’s a decent start.  You need to load prototype to use this, btw.

 

Greg

 

 

 


From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Tom Riley
Sent: Friday, March 17, 2006 9:56 AM
To: rails-spinoffs@lists.rubyonrails.org
Subject: Re: [Rails-spinoffs] good _javascript_ xml parser

 

This might not be practical for you, but the google maps api has an xml parser that uses a native xml parser if the browser has one and a _javascript_ parser if the browser doesn't.

 

 

Also, just found http://xmljs.sourceforge.net

 

 

On 17 Mar 2006, at 16:46, Gregory Hill wrote:



Hmm… that is a pretty cool class.  I was hoping more for something that you didn’t need to know what the tag names were, it would just create a hierarchy that you could drill down into easily, but if I get stuck, this is a good backup.

 

Greg

 


From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] On Behalf Of Maninder, Singh
Sent: Friday, March 17, 2006 9:34 AM
To: rails-spinoffs@lists.rubyonrails.org
Subject: RE: [Rails-spinoffs] good _javascript_ xml parser

 

Maybe this would help you :)

 

Thank you,
Mandy.

 

p.s. I have not written this. I got this from some site long time back.

 

 

XMLParser = Class.create();
Object.extend(XMLParser.prototype, {
  initialize: function(xmlObj) {
    this.xmlObj = xmlObj;
    this.root = xmlObj.documentElement;
  },
  list: function(value) {
    var result = this.root.getElementsByTagName(value);
    return result;
  },
  get: function (node, value) {
    if(typeof value != 'undefined')
      node = node.getElementsByTagName(value).item(0);
    return this.text(node);
  },
  toArray: function(value) {
    var list = this.list(value);
    var nodeValues = new Array();
    for (var i = 0; i < list.length; i++) {
      nodeValues.push(this.get(list[i]));
    }
    return nodeValues;
  },
  text: function (node) {
    if (typeof node.textContent != 'undefined') {
      return node.textContent;
    }
    else if (typeof node.innerText != 'undefined') {
      return node.innerText;
    }
    else if (typeof node.text != 'undefined') {
      return node.text;
    }
    else {
      switch (node.nodeType) {
        case 3:
        case 4:
          return node.nodeValue;
          break;
        case 1:
        case 11:
          var innerText = '';
          for (var i = 0; i < node.childNodes.length; i++)
          {
            innerText += text(node.childNodes[i]);
          }
          return innerText;
          break;
        default:
          return '';
      }
    }
  }
});
XMLParser.nodeType = [
    "",
    "ELEMENT_NODE",                 // 1
    "ATTRIBUTE_NODE",               // 2
    "TEXT_NODE",                    // 3
    "CDATA_SECTION_NODE",           // 4
    "ENTITY_REFERENCE_NODE",        // 5
    "ENTITY_NODE",                  // 6
    "PROCESSING_INSTRUCTION_NODE",  // 7
    "COMMENT_NODE",                 // 8
    "DOCUMENT_NODE",                // 9
    "DOCUMENT_TYPE_NODE",           // 10
    "DOCUMENT_FRAGMENT_NODE",       // 11
    "NOTATION_NODE"                 // 12
];

 

<*cript language="_javascript_" type="text/_javascript_">
var xmlParser = new XMLParser(originalRequest.responseXML);
var items = xmlParser.list('item');
for (var i = 0; i < items.length; i++) {
  var id = xmlParser.get(items[i], 'id');
  var name = xmlParser.get(items[i], 'name');
  
  $('result').value += id + ', ' + name + '\r\n';
}
var names = xmlParser.list('name');
for (var i = 0; i < names.length; i++) {
  $('result').value += xmlParser.get(names[i]) + '\r\n';
}
var ids = xmlParser.toArray('id');
for (var i = 0; i < ids.length; i++) {
  $('result').value += 'id:' + ids[i] + '\r\n';
}
</*cript>
<textarea id="result" cols="60" rows="10" ></textarea>

 

<?xml version="1.0" encoding='euc-kr'?>
<list>
  <item>
    <id>1</id>
    <name>a1</name>
  </item>
  <item>
    <id>2</id>
    <name>a2</name>
  </item>
  <item>
    <id>3</id>
    <name>a3</name>
  </item>
</list>

_______________________________________________

Rails-spinoffs mailing list

 

_______________________________________________
Rails-spinoffs mailing list
Rails-spinoffs@lists.rubyonrails.org
http://lists.rubyonrails.org/mailman/listinfo/rails-spinoffs

Reply via email to