viernes, 9 de marzo de 2012

jQuery: accessing XML doms created with $.parseXML and problems with append(string)

In the project raphaelmarkup I'm exploiting jquery API for loading and manipulating XML. First I parse the XML sources and then I can use jquery API for accessing and manipulating it. A documented example:

//some xml string example. the XML must not have any <!doctype definition
var xmlStr = '<p><o><b></b></o><b></b></p>';

//create a jquery dom object for that xml document.
var xmldoc1 = $.parseXML(xmlStr); //the native XMLDocument object
var dom = $(xmldoc1); //the jquery DOM object that we will use fopr accessing

//finds some element and sets attributes using the jquery API
dom.find("p>o").attr("attr1", "val1");


This has some advantages: its uses the internal XML browser parser, the jquery API is a portable way of accessing the XML DOM.

Now I want to document a problem that I had with this using jquery's append(String) method.
In the previous example, dom.find("p").append("hello) won't work. This is mainly because append(String) method will create the new elements using the global html document (the global "document variable) instead or using our XML document object. So we must do the following for appending an element :


var g1 = $(xmldoc1.createElement("g"));
dom.find("p>o").append(g1);
g1.test("hello");


the complete example based on qunit (ok() is an assertEquals()) :

var xmlStr = '

'
var dom = $($.parseXML(xmlStr));

ok(dom.find("b").size()==2, "jquery xml dom 1"); //OK

//set attribute and check -
dom.find("p").attr("attr1", "val1");
ok(dom.find("p").attr("attr1")=="val1", "jquery xml dom 12");
ok($("p", dom).size()==1, "13");//OK

/* a bug, using dom.find("p").append('<d>hello</d>') won't work. it seems
jquery won't let creation of non HTML valid code. */

dom.find("p").append('<d>hello</d>'); //this doesn't work
ok(dom.find("d").size()==1, "jquery xml dom 2"); //FAIL!

/* but this way works. Don't use append(string) but create the element
manually, and pass the dom object to append() */

var c1 = $(dom.get(0).createElement("c")); //make sure new el is created in our xml doc
dom.find("p").append(c1);
ok($("c", dom).size()==1, "14"); //OK



A function for creation of arbitrary xml elements :




/**
* create a new element in raphael XML dom
* @param parent an html dom or jquery selector or object
* where to append the created child.
* @return the created jquery dom element
*/
createElement: function(parent, tagName, attrs) {
parent=$(parent);
var xmldoc = null;
//if they send us a document, we append it on the documentElement

if(rm.isDocument(parent)) {
parent=$(parent.prop("documentElement"));
}
xmldoc=parent.prop("ownerDocument");

var e = $(xmldoc.createElement(tagName));
if(attrs)
e.attr(attrs);

parent.append(e);

return e;
},


Being a great tool for parsing and accessing xml documents in xhtml documents, It is a shame that jquery don't let to use arbitrary xml markup strings in methods like append, prepend, etc. :( But it seems that it is a thing we can live without

No hay comentarios: