3

OK I'll try to explain this as simple as possible;

I'm trying to parse XML that I get through web service, using jQuery. All is doing as it should, until I've noticed that for the love of God I can't parse a node that is named "image". long story short (and 2 hours later) I've noticed, that the problem is in the TAG NAME. Obviously, "image" is a reserved word or something like that???

Here's a demonstration; firstly, I simulated xml, that has "image" node and won't display any results. Secondly, I simulated the SAME xml, the SAME parsing, I just renamed "image" to "image1" and it WORKS. See the example here: http://jsbin.com/evinah/1/edit

So, obviously I can't change the web service, it's not in my domain. How do I get the "image" value, using jQuery?

Thanks for your responses.

0

3 Answers 3

3

How to solve the problem is already mentioned in other answers, but I thought it is important to explain what's "wrong" with image tags.

When you pass the XML string to jQuery, it will use the browser's native DOM methods to parse the XML. Those DOM methods are mainly for parsing and processing HTML though.

Lets see what happens when you create a root element:

> var e = document.createElement('root');
  <root></root>

console.log(e) lists a bunch of properties, but most importantly, this elements inherits from HTMLUnknownElement, which makes sense.

Now lets create an image element:

> var e = document.createElement('image');
  <img>

Uh? Where is <image></image>? Turns out that image is an alias for img. The new element inherits from HTMLImageElement.

You might think now that you could just do .children('img').text(), but this won't work since img elements cannot have descendants. The resulting structure that the browser produces is:

<root>
    <item>
        <img>
        image link
    </item>
    <item>
        <img>
        image link2
    </item>
</root>

The text nodes are siblings of the img elements, not descendants.

Sign up to request clarification or add additional context in comments.

Comments

2

You should use $.parseXML if you are handling a string, this will return a valid valid XML document that can be used with jQuery.

$($.parseXML(xml)).find('item').each(function(i, e){
  alert($(e).children('image').text());
});

(See it here.)

If you are using AJAX then you should set the dataType option to xml.


The main reason why $(xml) partially works without using $.parseXML except for the <image>, it is because <image> elements are transliterated to <img> elements during the DOM construction. On top of it, <img> is an empty element and won't contain any children text elements which messes up the XML structure.

For further information about the <img> and <image> historical usage please refer to <img> vs <image> tag in HTML.

4 Comments

Thank you so much for your answer! On a related note: what did I actually do with just $(xml) and why did it parse everything else OK, except "image" tag?
@NoneNone: You used the existing (HTML) DOM methods to parse XML. A quick test showed that var a = document.createElement('image'); actually creates an img element, so $(e).children('img').text() might have worked.
@NoneNone: I correct myself, $(e).children('img').text() does not work, but for different reasons.
@NoneNone, I updated my answer with a link to a question addressing this. (For my self curiosity I am still looking if this is present in the HTML(4|5) specification)
2

The $ function is not meant to be used for parsing XML. You have to use $.parseXML, and then wrap this in a jQuery object: $($.parseXML(...)). In fact, for HTML there is also a dedicated function $.parseHTML. The $ function called with a string should be used either with a selector, or a simple "<tag>" string.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.