Wednesday, December 12, 2007

[Javascript] XML Loading

Problem: writing down a custom visual XML editor (based upon a specific and complex XSD schema definition), the first task was parsing XML string / remote XML file into a DOM compliant document object.



Solution: the first task is to recognize Explorer and Mozilla browser compliance. This can be surprisely done by checking browser's capability to handle XML content, that is to say wich objects the browser can use.
To achieve this target, I used those global variables:

var isIE = (window.ActiveXObject)?true:false;
var isMozilla = (document.implementation.createDocument)?true:false;

That means if you can instantiate an ActiveXObject, you are Explorer, while if you can execute che createDocument method you certanly are Mozilla compliant.
I have no documentation of the reason of those differences, exception made by the fact that Explorer fully operates with ActiveX objects).

Next step depends on the way you want to open XML data: from a file or from a string.
In the first case this is the code:

var xmlDoc  = null ;
function importXML(url)
{

if (isMozilla)
{
xmlDoc=document.implementation.createDocument("","",null);
xmlDoc.onload = onContentLoad;
}
else if (isIE)
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.onreadystatechange = function () {
if (xmlDoc.readyState == 4) onContentLoad()
};
}
else
{
alert('Your browser can\'t handle this script');
return;
}
xmlDoc.load(url);
}
function onContentLoad()
{
/* handle the loaded content */
}
As you can see I used a global variable "xmlDoc" wich is the DOM document: this is correct in a procedural coding style, but in my opinion would be better to put it into OOP style (so "xmlDoc" becomes a member of the class).
The function simply load different object is case of IE or Mozilla, and as the file is supposed to be in another domain - it can take several time to load - after the loading is called the "onContentLoad" function, in wich you do wathever you want to inizialize your application.

I used this method to load some XML templates or create a new XML document, useful to create new fragment of the defined document (insted of inserting XML logic into javascript code, is better to load a specific fragment, so if your schema definition changes, your javascript script is still effective).

I use a Java Servlet in my application, that aswers HTTP requests: one of this requests is a "loadSchema" request, with wich I receive in a string an entire XML document (wich itself describes the schema - not a XSD schema - of a specific application behavior): so the problem is to parse a string into an XML document.
This is the code:

function loadXML(xmlString)
{
if (isIE)
{
this.xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
this.xmlDoc.loadXML(xmlString);
}

else if (this.isMozilla) {
var domParser = new DOMParser();
this.xmlDoc = domParser.parseFromString(xmlString,"application/xml");
}

if(
xmlDoc==null)
alert("Error.");
}

Code is quite simple, so no explanation is needed.

Ending, this is the code to handle a "GET" HTTP request via Javascript (off course there can be many ways to customize this code, there are several options, but guys...this is butchering!):

var xmlHttp = null;

function requestSchema(url)
{
xmlHttp=GetXmlHttpObject()
if (xmlHttp==null)
{
alert ("Browser does not support HTTP Request")
return
}
xmlHttp.onreadystatechange=stateChangedRequestSchema;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}

function stateChangedRequestSchema()
{
if (xmlHttp.readyState==4 xmlHttp.readyState=="complete")
loadXML(xmlHttp.responseText);
}

The "requestSchema" simply makes the GET request, and delegates "stateChangedRequestSchema" to handle the load event (calls "loadXML" passing the content received by the request, that is supposed to be a valid XML document....but you have to write down the code to check if it is correct!).

Once loaded the content in the DOM object, you can use all DOM compliance methods to navigate into your document and do wathever you want. A good and quick reference to javascritp DOM reference can be found here.

You should not be surprised or highly shocked if handling XML content is so simple: HTML is an XML based language itself, so it would have been fucking idiot not to support natively XML parsing.

Bye Bye, hope to help you!

2 comments:

Johnny Idol said...

Scuffia, you are my XML hero.

Johnny Idol said...

Scuffia we need some XML boost about JAVA DOM. give us a post, we need your knowledge here @ BrainS