Saturday, October 30, 2010

Firefox: parsing client-side XML file.

Firefox browser has an interesting feature: reading client-side files(txt,xml,image).

It's possible through the File Object provided by FF.

I am showing here how to parse the client-side XML file and show its tree structure. I also used the drag and drop (FF v3.5+) and embedded image (DataURI) features.



below is the screenshot showing the xml file parsed.

Code:

<html>
<head>
<title>Dragdrop local XML file:view it's Tree</title>
<script>
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var xType = /xml.*/;

if (!file.type.match(xType)) {
continue;
}
//preview.appendChild(img);
var xmltxt="";
var reader = new FileReader();
reader.onload = function(e) {
ParseXml(e.target.result);
};
reader.onerror = function (err){ alert(err.message); };
reader.readAsText(file);
}
}
var nodeArr=[];
function ParseXml(axmltxt)
{ var parser=new DOMParser();
var xmlDoc=parser.parseFromString(axmltxt,"text/xml");
TraverseXml(0,xmlDoc.childNodes); //get child nodes,iterate & show.
if(nodeArr.length>0)
showXmlTree();
}
//--------------
function TraverseXml(num,nodes)
{
for(var i in nodes)
{
if(nodes[i].isElementContentWhitespace)
continue;
if(nodes[i].nodeType==3) //if textnode, append #
{
nodeArr.push([num,'#'+nodes[i].nodeValue]);
}
else
{
if(nodes[i].nodeName != undefined)
nodeArr.push([num,nodes[i].nodeName]);
}
if(nodes[i].childNodes)
{
TraverseXml(num+1,nodes[i].childNodes)
}
}
}

function showXmlTree()
{
var preview = document.getElementById("TreeContainer");
preview.innerHTML = '<table border="0" cellspacing="0" cellpadding="0" class="clsTbl"></table>';
preview = preview.firstChild; //table
for(var i in nodeArr)
{
var inArr=nodeArr[i];
if(inArr[0]==0)
{
preview.innerHTML+='<tr><td><div>'+inArr[1]+'</div></td></tr>';
}
else
{
var padval=inArr[0]*20;
preview.innerHTML+='<tr><td><div><img src="xyz/nothing.xx" onerror="imgload(this)" style="padding-left:'+
padval+'px;"/>'+inArr[1]+'</div></td></tr>';
}
}
}

function imgload(me)
{
me.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAADhJREFUOE9j/P//PwMGYGRkxCoOUgiUIAlg14DHoFEb4OE7CEMJklYgqQOZpF7SwJO6qJQ08NgAANtrsm6oziaWAAAAAElFTkSuQmCC";
}
//--------------
function dragenter(e) {
e.stopPropagation(); //stops event propagation to parent.
e.preventDefault(); //stop default action (event).
}

function dragover(e) {
e.stopPropagation();
e.preventDefault();
}

function drop(e) {
e.stopPropagation();
e.preventDefault();

var dt = e.dataTransfer;
var files = dt.files;

handleFiles(files);
}

window.onload=function(){
var dropbox;
dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
}
</script>
<style>
.obj{ width:150px;height:150px; }
TABLE.clsTbl{
table-layout:fixed;font-family:Verdana;font-size:10pt;border:solid 1px blue;
}
</style>
</head>
<body>
<h4>Drag and drop any of your local XML file into the below box. <br/>
It parses the XML file and shows its tree structure below the box. try it.<br/>
(tested in FF v3.6 browser).</h4>
<div style="width:100px;height:100px;background-color:pink;" id="dropbox"> </div>
<br/>
<div style="margin:10px;width:40%;" id="TreeContainer"> </div>
</body>
</html>




you can try it online or download here .


References:
https://developer.mozilla.org/en/DOM/File
https://developer.mozilla.org/En/DragDrop/Drag_and_Drop