views:

1661

answers:

3

Consider this problem:

Using Javascript/E4X, in a non-browser usage scenario (a Javascript HL7 integration engine), there is a variable holding an XML snippet that could have multiple repeating nodes.

<pets>       
 <pet type="dog">Barney</pet>
 <pet type="cat">Socks</pet>
</pets>

Question: How to get the count of the number of pet nodes in Javascript/E4X ?

EDIT: To clarify, this question should be around E4X (ECMAScript for XML). Apologies to those who answered without this information. I should have researched & posted this info beforehand.

+2  A: 

I'd say... use jQuery!

  var count = 0;
  $(xmlDoc).find("pet").each(function() {
          count++;

          // do stuff with attributes here if necessary.
          // var pet = $(this);
          // var myPetType = pet.attr("type");
       };
  });

EDIT: Can't use jquery... ok, let's do it in regular javascript :(

      var pets= xmlDoc.getElementsByTagName("pet");
      for ( var i = 0; i < pets.length ; i++ )
      {
          count++;
         // var petObj = {
         //     pets[i].getAttribute("type")
         //  };
      }
womp
Nice. However `$` is not meant for arbitrary xml strings, it's meant for html. It works by accident in this particular case. Guaranteed to work is `$(xmlDoc)` (ie the DOM document representing `xmlstring`).
Crescent Fresh
Great answer! Unfortunately JQuery is not available to me, as the JS is not in a browser or able to make references to external libraries. This answer gets an upvote anyway!
p.campbell
100% correct. find() works on elements, not text, which isn't too clear from my variable name. I guess I should make that clearer.. good call.
womp
-1, you didn't use the `length` property with either `jQuery` or `getElementsByTagName()`.
Ionuț G. Stan
Ionut, both my code samples provided for manipulating the pet nodes instead of just getting the count. This is because the original question before the edit stated something about looking for duplicate nodes.
womp
+1  A: 

Using the DOM you can call getElementsByTagName().

alert( document.getElementsByTagName( "pet" ).length );

More information:

https://developer.mozilla.org/en/DOM:element.getElementsByTagName

You're going to need to obtain the XML document somehow. XHR, for example, returns documents as parsed XML.

var xhr = new XMLHttpRequest();  
xhr.open( 'GET', 'http://domain.com/pets.xml', true );  
xhr.onreadystatechange = function ( e ) {  
    if ( xhr.readyState == 4 && xhr.status == 200 )
        alert( xhr.responseXML.getElementsByTagName( "pet" ).length );
};
xhr.send( null );
Alan Gutierrez
+2  A: 

Use an E4X XML object to build an XMLList of your 'pet' nodes. You can then call the length method on the XMLList.

//<pets>
//    <pet type="dog">Barney</pet>
//    <pet type="cat">Socks</pet>
//</pets>  

// initialized to some XML resembling your example
var petsXML = new XML("");  

// build XMLList
var petList = petsXML['pet'];  

// alternative syntax
// var petList = petsXML.pet;  

// how many pet nodes are under a given pets node?
var length = petList.length();
csj
Can't you just do:petsXML.pet.length();
Niko Nyman
Absolutely, and in fact I would normally do just that! I just wanted to break things apart to clarify that .pet (or ['pet']) returns and XMLList object, and that length() is a method call on that type.
csj