views:

2271

answers:

4

Suppose I get the following XML structure:

<root>
<item>
 <item1>text1</item1>
 <item2>text2</item2>
 more text here
</item>
</root>

"more text here" is a text node that is at the same level as the other data nodes in the hierarchy but it does not seem to be accessible.

Is there a way of extracting the text node shown above using jQuery functions?

+2  A: 

So the solution I came up with is to delete the item1 and item2 nodes leaving only the text:

    $(responseXML).find('item').each(function(){
         var item1_text = $(this).find('item1').text();
         var item2_text = $(this).find('item2').text();

         $(this).contents().empty(); //removes the other nodes

         var extra_text = $(this).text();

    }
safoo
+2  A: 

I came up with the same solution:

  var xml = $("<root><item1>text1</item1><item2>text2</item2>more text here</root>");
  alert($(xml).contents().empty().end().text());
Jose Basilio
+2  A: 

Use the contents() function. For example, if you have an XML fragment like:

var root = $('<root><item1>text1</item1><item2>text2</item2>more text here</root>');

Then you can get at the text via:

var txt = root.contents()[2]

That is assuming that the text node is always the 3rd child of <root>. Otherwise, if you do not know the position, or may have a node that contains multiple text nodes, you should collect all of the text nodes by filtering:

var textList = root.contents().filter(function() { return this.nodeType == 3; });

This returns an array of text nodes that are found in the XML fragment. To get at the strings in the list, just access the array slice:

var txt = textList[0];
johnvey
Did you try your code before posting it? None of the examples you posted work.
Jose Basilio
Yes, I just retested by cutting and pasting into jquery 1.3.2. Since these are all variable assignments, firebug won't print anything if you just cut and paste -- you have to echo it back, or just omit the assigment.
johnvey
+1 for non-destructive solution.
Niklas
A: 

This will get the proper root/text value. The text can be placed everywhere in the root node.

<script type="text/javascript"> $().ready(function() { var xml = $('#xml').find('root').contents().each(function(i){ if (this.nodeName=="#text" && this.nodeType=="3" && this.nodeValue.length>2) alert(this.nodeValue); }); }); </script>

for:

<div id="xml"><root><item1>text1</item1><item2>text2</item2>more text here</root></div>

Note: "inline" xml is not working in Internet Explorer, but if you replace root and itemX in the example with valid Html nodenames, it will work too.

Explanation: DOM treats empty and text nodes as Elements. if you debug the above .each(), you'll see the following:

alert( this.nodeName + '|' + this.nodeType + "|" + this.nodeValue);

#text|3| , ITEM1|1|null , #text|3| , ITEM2|1|null , #text|3| more text here

(Sorry, formatting is not working with a Hungarian keyboard, still)

balint