Search code examples
javascriptjqueryfirefoxxmldocument

JQuery can't find element in XMLDocument only in Firefox


I have a call to a webservice that is returning the next raw response

    HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 1516
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Date: Fri, 12 Feb 2016 10:28:58 GMT

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Body>
        <OperationListResponse xmlns="http://tempuri.org/">
            <OperationListResult xmlns:a="http://schemas.datacontract.org/2004/07/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
                <a:data>123</a:data>
                <a:operation_id i:nil="true"/>
                <a:status>OK</a:status>
            </OperationListResult>
        </OperationListResponse>
    </s:Body>
</s:Envelope>

When I get this XML in my javascript code, I'm trying to read the element "status" using the next code:

//dataResponse is my javascript valid XMLDocument
x = $(dataResponse).find('status').text();

And instead of getting "OK", I'm getting "". This only happens in Firefox. The weird thing is that it works great in Chrome, Opera, Edge and Safari. While debugging in Firefox, making a watch to the dataResponse object, I can actually see that the node "status" has the value "OK".

enter image description here

Any clue on how to solve this issue?

Edit: I've tried doing the changes that Jai suggested, and I got weird results from firefox. If I Watch a variable that makes the "find", I can see the text. If i try to find by directly typing the "$(dados).find('a\:status').text()", i cant see any results. Firefox watch panel: enter image description here

Chrome watch panel: enter image description here


Solution

  • Jquery probably doesn't have anything to do with this, besides being the wrong tool for the job. For element lookups it mostly delegates to querySelectorAll. XML Documents have namespaces, and selectors have special handling for namespaces.

    But namespace shorthands require that mappings from shorthand to namespace URIs are first declared. E.g. XPath lookups do that through Document.evaluate's namespace resolver argument and selectors in stylesheets retrieve them from @namespace declarations

    querySelectorAll does not take arguments that support such namespace resolution, therefore only no-namespace, default-namespace and any-namespace selectors can be specified.

    In other words, it's not possible to match a status element in the a -> http://schemas.datacontract.org/2004/07/ namespace with a a|status selector through querySelectorAll, in fact, it should actually throw an exception. And a:status would just be a pseudo element selector that's not known to the browser.

    A more generic *|status selector should match it, but it could potentially overmatch by also selecting status elements from other namespaces.

    If you want to do namespace-aware traversal in XML documents you probably should use XPath instead.