1

I am looking for an AJAX JavaScript library that supports namespaced xml.

I read dozens of posts on the web (including on stackoverflow) but didn't find a good answer. There are many AJAX examples, but they break as soon as namespaces come into play (it is the case for example with jQuery selectors).

Christophe
  • 27,383
  • 28
  • 97
  • 140

1 Answers1

0

I do not know exactly what you are calling an "AJAX JavaScript library" – making HTTP requests is a problem different from accessing nodes in a document tree.

If you understand a library as "a collection of resources used to develop software" (Wikipedia), then, as part of the JSX library, I have written rather compatible¹ wrappers for XMLHttpRequest and namespace-aware DOM Level 3 XPath: http.js and xpath.js.

http.js supports synchronous and asynchronous processing in the same way, and can even access the local filesystem (if permission is granted). Because JSX qualifies as a library then, you can use http.js and xpath.js either separately, with foreign code to complement either one, or together.

You would use them together, for example, as follows. Suppose you had an XML document with resource name test.xml like

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Body>
    <res:Response
        xmlns:res="http://domain.example/Response">
      <res:OUTPUT>
        <res:UNDO_COUNT>1.0</res:UNDO_COUNT>
        <res:MSG>Undo complete (No more to undo)</res:MSG>
      </res:OUTPUT>
    </res:Response>
    <res:OUTPUT
        xmlns:res="http://domain.example/Response">
      foo
    </res:OUTPUT>
  </soap:Body>
</soap:Envelope>

and you wanted to extract the 1.0 from its res:UNDO_COUNT element, you could write:

<!-- 1. Include prerequisites and dependencies using Resource Builder (recommended) -->
<script type="text/javascript" src="builder.php?src=object,string,http,xpath"></script>

<script type="text/javascript">
  /*
   * 2. Construct the HTTP request wrapper; 
   *    the default is a GET request with asynchronous handling
   */
  var request = new jsx.net.http.Request("test.xml");

  /* 3. Prepare processing of the HTTP response */
  request.setSuccessListener(function (response) {
    /* 5. Get the reference to the XMLDocument object */
    var doc = response.responseXML;

    /* 6. Create the namespace resolver that fits your query best */
    var nsResolver = jsx.xpath.createFullNSResolver(null, doc);

    /* 7. Make the XPath query */
    var nodes = jsx.xpath.evaluate("//res:UNDO_COUNT/text()", doc, nsResolver);

    /*
     * 8. Process the result.  jsx.xpath.evaluate() returns a reference
     * to an Array instance if you do not specify the result type.
     */

    /* "1.0" */
    console.log(nodes[0].data);
  });

  /* 4. Make the HTTP request */
  request.send();
</script>

See also: Parsing XML / RSS from URL using Java Script

¹ A combination of JSX:object.js, http.js, and xpath.js has been tested positive in Gecko-, WebCore-, MSHTML-based and Opera browsers. However, JSX is mostly experimental code for now.

Testcase, see script console

Constructive feedback is welcome. In addition, JSX is free software. (You cannot do a checkout yet, but I am working on it.)

Community
  • 1
  • 1
PointedEars
  • 14,752
  • 4
  • 34
  • 33
  • I am interested in both request and response processing (my main issue being the latter). Thanks for the reply, I'll take a look at your wrapper. Did you test it in Internet Explorer 7/8/9? As for the last link, I am afraid there is nothing relevant as soon as namespaces come into play. – Christophe Dec 12 '11 at 17:34
  • I could not test the HEAD revision of xpath.js (committed today) in IE 7 to 9 yet. I tested it positive in IE 6.0.2800.1106 on Wine, so MSXML's `selectNodes` is supported, and I do not expect surprises in later IE versions (same DOM). As for making HTTP requests, look into JSX:http.js (see edit). That has been tested in the named browsers, including IE 7 and 8 at least, and is powering commercial sites (although those run slightly older JSX revisions, of course). – PointedEars Dec 12 '11 at 19:07
  • @Christophe What do you mean - nothing relevant? RSS/XML uses namespaces. You need a namespace resolver to find those elements with XPath. My previous posting shows how to make and use one. `jsx.xpath.create…NSResolver()` build on that. – PointedEars Dec 13 '11 at 10:03
  • sorry, I'll need to take a closer look. I just saw the use of getElementsByTagName, which will break as soon as namespaces are involved. – Christophe Dec 13 '11 at 16:39
  • @Christophe I have updated the description and merged the two examples into one use-case, so that you can see better how the scripts can work together. – PointedEars Dec 13 '11 at 18:08
  • Thanks! I need to test it in IE. What is the point of Resource Builder btw? – Christophe Dec 13 '11 at 19:40
  • Thanks for the points. Resource Builder reduces the script (and style) footprints for the Web (while preserving the code for editing) by removing unnecessary comments, and [reduces the number of HTTP requests](http://code.google.com/speed/page-speed/docs/rtt.html) for each resource type to one. I might even add automated minification later. The ultimate goal is to resolve dependencies automatically without relying on client-side triggered loading (AFAIK, unlike other libraries). – PointedEars Dec 13 '11 at 21:32
  • I have added a link to a *live* testcase. – PointedEars Dec 19 '11 at 22:33