tags:

views:

525

answers:

4

Hi,

I'm trying to check if a value in an xml node exists using Jquery. The xml string is:

  <SectionAnswers>
   <SectionAnswer>
    <detailID>2216</detailID>
    <SourceAnswerID>979</SourceAnswerID>
   </SectionAnswer>
   <SectionAnswer>
    <detailID>2218</detailID>
    <SourceAnswerID>981</SourceAnswerID>
   </SectionAnswer>
   <SectionAnswer>
    <detailID>2219</detailID>
    <SourceAnswerID>977</SourceAnswerID>
   </SectionAnswer>
   <SectionAnswer>
    <detailID>2221</detailID>
    <SourceAnswerID>980</SourceAnswerID>
   </SectionAnswer>
   <SectionAnswer>
    <detailID>2282</detailID>
    <SourceAnswerID>64</SourceAnswerID>
   </SectionAnswer>
   <SectionAnswer>
    <detailID>2283</detailID>
    <SourceAnswerID>978</SourceAnswerID>
   </SectionAnswer>
   <SectionAnswer>
    <detailID>2596</detailID>
    <SourceAnswerID>73</SourceAnswerID>
   </SectionAnswer>
  </SectionAnswers>

When I try to query it for a value by using the following:

$("SectionAnswers", Section).find("64") //Section is the jquery context

I get the following response:

Expression does not return a DOM node.

.//-->64<--

Any ideas where I'm going wrong with this? I really don't want to loop through them checking the value each time as in $("SectionAnswers", Section).each()

Thanks

A: 

I'm leaving this here for reference, since it could be useful in slightly different circumstances, but, like karim79 mentioned, it matches anything that has 64 as a substring.


You should be able to use the ":contains(text)" pseudo-selector:

$("SectionAnswers SourceAnswerID:contains('64')", Section)

That will select the SourceAnswerID elements, so you might need to use the parent() or closest() function to move up the hierarchy.

Matthew Crumley
The problem with that is it will have to be filtered down further in case of matches like 164, 3064 etc, so the question is whether to use contains() and further filter the results or loop through each node until that value is matched.
karim79
Good point. I forgot :contains allowed partial matches.
Matthew Crumley
+1  A: 

Try traversing the XML using a simple $.each:

$('SectionAnswers > SectionAnswer').each(function() {
    if($(this).find('SourceAnswerID').text() == '64') {
        alert('Found 64 at detailID: ' + $(this).find('detailID').text());
    }
});

or using filter:

var $sa = $('SectionAnswers > SectionAnswer').filter(function() {
    return $(this).find('SourceAnswerID').text() == '64'; 
});
alert($sa.find('SourceAnswerID').text());
alert($sa.find('detailID').text());
karim79
You could also use filter if you want to get a jQuery object with just the desired element(s).
Matthew Crumley
A: 

Thanks guys.

I'll play around with both of those and see what I can come up with. I want to avoid a loop if possible because it will already be running inside of a loop and I just have a button about nested loops...

But now that I think about it... Both the filter and contains calls are loops internally anyways... So it might actually perform better it just simply get the collection and iterate through it.

A: 

OK got a fix. I ended up changing the xml to make the IDs attributes so it is

  <SectionAnswers>
   <SectionAnswer SourceAnswerID="1487"
         detailID="1420" />
   <SectionAnswer SourceAnswerID="1488"
         detailID="2039" />
  </SectionAnswers>

And I can now find it via

find("SectionAnswer[SourceAnswerID=1487]")

It's a better solution anyway as putting the info in attributes cuts down on the size of the return value.