walking through an xml dom tree through javascript

satya - Mon Oct 08 2012 22:50:05 GMT-0400 (Eastern Daylight Time)

DOM API reference from w3c

DOM API reference from w3c

satya - Mon Oct 08 2012 22:51:58 GMT-0400 (Eastern Daylight Time)

ajax dom

ajax dom

Search for: ajax dom

satya - Mon Oct 08 2012 23:48:15 GMT-0400 (Eastern Daylight Time)

javascript array push method

javascript array push method

Search for: javascript array push method

satya - Mon Oct 08 2012 23:49:06 GMT-0400 (Eastern Daylight Time)

example


var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.push("Kiwi")

satya - Mon Oct 08 2012 23:49:39 GMT-0400 (Eastern Daylight Time)

Consider this


<somenode>sometextvalue</somenode>

satya - Mon Oct 08 2012 23:51:55 GMT-0400 (Eastern Daylight Time)

The node structure is


Node1: somenode
Node1 value:null
   Node2 (child of node1): sometextvalue
   Node2 value: sometextvalue

satya - Mon Oct 08 2012 23:52:17 GMT-0400 (Eastern Daylight Time)

Consider this


<somenode/>

satya - Mon Oct 08 2012 23:52:48 GMT-0400 (Eastern Daylight Time)

The node structure is


Node1: somenode
Node1 has no child nodes

satya - Mon Oct 08 2012 23:53:22 GMT-0400 (Eastern Daylight Time)

Of course this is assuming you have no embedded html inside the xml tags

Of course this is assuming you have no embedded html inside the xml tags

satya - Wed Oct 10 2012 21:50:59 GMT-0400 (Eastern Daylight Time)

Node types


1	ELEMENT_NODE
2	ATTRIBUTE_NODE
3	TEXT_NODE
4	CDATA_SECTION_NODE
5	ENTITY_REFERENCE_NODE
6	ENTITY_NODE
7	PROCESSING_INSTRUCTION_NODE
8	COMMENT_NODE
9	DOCUMENT_NODE
10	DOCUMENT_TYPE_NODE
11	DOCUMENT_FRAGMENT_NODE
12	NOTATION_NODE

satya - Wed Oct 10 2012 21:51:26 GMT-0400 (Eastern Daylight Time)

Node types reference from w3schools

Node types reference from w3schools

satya - Wed Oct 10 2012 22:37:12 GMT-0400 (Eastern Daylight Time)

Some key apis


nodeObj.nodeName
  .nodeType
  .nodeValue
  .hasChildNodes()
  .childNodes //ChildNodeList
  .childNodes.item(i) //nodeObj
  .childNodes.length

satya - Wed Oct 10 2012 22:52:51 GMT-0400 (Eastern Daylight Time)

Here is some quick, possibly, trashy code


function realXmlToJson1(objectNode)
{
    // Create the return object
    var obj = {};

    alert("Processing:" + objectNode.nodeName);
    
    for(var i = 0; i < objectNode.childNodes.length; i++) 
    {
        //item is the node
        //childnodes is the nodelist
        var item = objectNode.childNodes.item(i);
        var nodeName = item.nodeName;
        
        //alert("processing:" + nodeName + ":" + item.nodeValue);
        var nodetype = getNodeType(item);
        
        if (nodetype == "attribute")
        {
            obj[nodeName] = item.nodeValue;
        }
        else if (nodetype == "emptynode")
        {
            //it is a text node
            //alert("adding an empty node:" + nodeName);
            obj[nodeName] = "";
        }
        else if (nodetype == "text")
        {
            var textValue = getTextNodeValue(item);
            //alert(nodeName + ":" + textValue);
            obj[nodeName] = textValue;
        }
        else
        {
            //alert("it is a collection:" + nodeName);
            var objArray = new Array();
            obj[nodeName] = objArray;
            processCollectionNode(item, objArray);
        }
    }
    return obj;
};

function processCollectionNode(colNode, objArray)
{
    //I am: <some-loop>
    //get my child
    //<row>
    //get an object for that row
    for(var i = 0; i < colNode.childNodes.length; i++) 
    {
        var rowNode = colNode.childNodes.item(i);
        var rowObject = realXmlToJson1(rowNode);
        objArray.push(rowObject);
    }
}

function getNodeType(xmlnode)
{
    if (xmlnode.nodeType == 2)
    {
        return "attribute";
    }
    //<some-node>....
    if (xmlnode.hasChildNodes() == false)
    {
        //no children
        //<some-node/>
        return "emptynode";
    }
    
    //the node has children
    //See if it has the following pattern
    //<some-node>hello value</some-node>
    
    var i = xmlnode.childNodes.length;
    var childnode = xmlnode.childNodes.item(0);
    //alert(childnode.nodeType);
    //3 - text
    //4 - text encoded in cdata
    if ((childnode.nodeType == 3) || (childnode.nodeType == 4))//text
    {
        return "text";
    }
    
    //Detect a pattern like this
    //<some-node><row><some-e>dddd</some-e></row></some-node>
    return "collection";
}

//Return the text value from a structure like
//<some-node>hello value</some-node>
function getTextNodeValue(xmlnode)
{
    return xmlnode.childNodes.item(0).nodeValue;
}

satya - Thu Nov 15 2012 22:31:01 GMT-0500 (Eastern Standard Time)

akc-xmltojson.js


var AKC;
if (!AKC) {
    AKC = {};
}
(function () {

    //**********************************************
    //Interface
    //**********************************************
    //aspireXmlToJson1(mainXmlObjectNode)
    AKC.aspireXmlToJson = aspireXmlToJson1;

    //deprecated
    AKC.objectXmlToJson = realXmlToJson1Wrapper;
    
    //JSONAtNode(mainXmlObjectNode, nodeName)
    AKC.getJSONAtNode = getJSONAtNode;


    //**********************************************
    //Implementations
    //**********************************************
    function getJSONAtNode(mainXmlObjectNode, nodeName, convertToLowercase)
    {
        var objectNode 
        = $(mainXmlObjectNode).find(nodeName)[0];
        if (objectNode == null)
        {
            alert("sorry null root node");
            return {};
        }
        return realXmlToJson1Wrapper(objectNode, convertToLowercase);
    }
        
    // Changes XML to JSON
    function aspireXmlToJson1(mainXmlObjectNode)
    {
        return getJSONAtNode(mainXmlObjectNode, "AspireDataSet",false);
    } 
    
function realXmlToJson1Wrapper(inObjectNode, inConvertToLowercase)
{     
    var convertToLowercase = (inConvertToLowercase == null) ? true : convertToLowercase;
    return realXmlToJson1(inObjectNode);
    
    function realXmlToJson1(objectNode)
    {
        // Create the return object
        var obj = {};
    
        //alert("Processing:" + objectNode.nodeName);
        
        for(var i = 0; i < objectNode.childNodes.length; i++) 
        {
            //item is the node
            //childnodes is the nodelist
            var item = objectNode.childNodes.item(i);
            var nodeName = item.nodeName;
            if (convertToLowercase == true)
            {
                nodeName = nodeName.toLowerCase();
            }
            
            //alert("processing:" + nodeName + ":" + item.nodeValue);
            var nodetype = getNodeType(item);
            
            if (nodetype == "ignore")
            {
                continue;
            }
            else if (nodetype == "attribute")
            {
                obj[nodeName] = item.nodeValue;
            }
            else if (nodetype == "emptynode")
            {
                //it is a text node
                //alert("adding an empty node:" + nodeName);
                obj[nodeName] = "";
            }
            else if (nodetype == "text")
            {
                var textValue = getTextNodeValue(item);
                //alert(nodeName + ":" + textValue);
                obj[nodeName] = textValue;
            }
            else
            {
                //alert("it is a collection:" + nodeName);
                var objArray = new Array();
                obj[nodeName] = objArray;
                processCollectionNode(item, objArray);
            }
        }
        return obj;
    };
    
    function processCollectionNode(colNode, objArray)
    {
        //I am: <some-loop>
        //get my child
        //<row>
        //get an object for that row
        for(var i = 0; i < colNode.childNodes.length; i++) 
        {
            var rowNode = colNode.childNodes.item(i);
            var rowObject = realXmlToJson1(rowNode);
            objArray.push(rowObject);
        }
    }
    
    function getNodeType(xmlnode)
    {
        //it is not an element
        if (xmlnode.nodeType != 1)
        {
            return "ignore";
        }
        //it is an attribute
        if (xmlnode.nodeType == 2)
        {
            return "attribute";
        }
        
        //<some-node/>....
        if (xmlnode.hasChildNodes() == false)
        {
            //no children
            //<some-node/>
            return "emptynode";
        }
        
        //the node has children
        //See if it has the following pattern
        //<some-node>hello value</some-node>
        
        var i = xmlnode.childNodes.length;
        //first child
        var childnode = xmlnode.childNodes.item(0);
        //alert(childnode.nodeType);
        //3 - text
        //4 - text encoded in cdata
        if ((childnode.nodeType == 3) || (childnode.nodeType == 4))//text
        {
            //Only one child to this element
            if (i==1) {
                return "text";
            }
        }
        //More than one child: (text, element)
        //Detect a pattern like this
        //<some-node><row><some-e>dddd</some-e></row></some-node>
        return "collection";
    }
    
    //Return the text value from a structure like
    //<some-node>hello value</some-node>
    function getTextNodeValue(xmlnode)
    {
        return xmlnode.childNodes.item(0).nodeValue;
    }
}//end-of-realXmlToJson1Wrapper    
})();

satya - Thu Nov 15 2012 22:32:09 GMT-0500 (Eastern Standard Time)

akc-widget.js


var AKC;
if (!AKC) {
    AKC = {};
}
(function () {

    //Interface
    //A class to facilitate akc widgets
    //Note this is not a function but a class
    AKC.AkcWidget = AkcWidget;
    
    //A utility function
    AKC.getFunctionObject = getFunctionObject;
    
    //deprecated: can be called internally
    AKC.akcWidgetSetup=akcWidgetSetup;
    
    //Takes no arguments
    //Returns an object containing URL details
    AKC.getAKCURLDetailsObject = getAKCURLDetailsObject;
    
    //Implementations
    function AkcWidget(inDataUrl, inTemplateUrl, divElement)
    {
        this.dataUrl = inDataUrl;
        this.templateUrl = inTemplateUrl;
        this.data = {};
        this.template = "";
        this.targetDivElement = divElement;
        var that = this;
        
        //alert(inDivId);
        //alert(this.targetDivId);
        
        function populateTargetDiv(innerHtmlString)
        {
            //alert("hello");
            //alert(that.targetDivId);
            $(that.targetDivElement).html(innerHtmlString);
        }
       
        populateTargetDiv("Begining my run");
        
        //Invoked from the callback function
        this.getHtml = function()
        {
            //alert( "hello I am done");
            //alert(JSON.stringify(that.data));
            //alert(that.template);
            $.templates( {"template1" : that.template} );
            var finalhtml = $.render.template1(that.data);
            //alert("final:" + finalhtml);
            populateTargetDiv(finalhtml);
            $(that.targetDivElement).show();
        }
        
        this.getTemplate = function()
        {
            //alert("getTemplate called");
            //alert(this.templateUrl);
            $.ajax({
              url: this.templateUrl,
              cache: false,
              dataType:"text",
              context: this,
              failure: ajaxFailure,
              success: replyFromGetTemplate
            });        
        }
        this.populate = function()
        {
            $.ajax({
              url: this.dataUrl,
              cache: false,
              dataType:"text",
              context: this,
              failure: ajaxFailure,
              success: replyFromGetData
            });      
        }
        function ajaxFailure()
        {
            alert('ajax failed');
        }    
        function replyFromGetData(data)
        {
            //alert("reply from get data");
            //alert(data);
            var dataxml = $.parseXML(data);
            var s = AKC.aspireXmlToJson(dataxml);
            //alert(JSON.stringify(s));
            this.data=s;
            this.getTemplate();    
        }
        
        function replyFromGetTemplate(data)
        {
            //alert("replyFromGetTemplate called");
            this.template=data;
            this.getHtml();
        }
        
    }//end-of-AkcWidget
    
//returns a function object given its name
//if the function is undefined return null
function getFunctionObject(functionname)
{
    var funcobject;
    eval("funcobject = " + functionname + ";");
    if (typeof(funcobject) == "function")
    {
        return funcobject;
    }
    else
    {
        //null is a javascript object
        return null;
    }
}
function akcWidgetSetup()
{
    //Get every element with the specified class
    var elementArray = $(".akc_expand");
    for(i=0; i<elementArray.length; i++)
    {
        //one of the divs
        var element = elementArray[i];
        //See if the element has href
        var type = $(element).attr("type");
        type = "akcExpand_" + type + "_function"; 
        var typeFuncObject = getFunctionObject(type);
        if (typeFuncObject == null)
        {
            alert("function doesn't exist:" + typeFuncObject);
            continue;
        }
        typeFuncObject(element);
    }
}//eof-local-function

//public function getAKCURLDetailsObject()
/*
<div id="AKCURLDetailsDivID" style="display:none">
    <urlname>{{url}}</urlname>
    <ownerUserId>{{ownerUserId}}</ownerUserId>
    <downerUserId>{{downerUserId}}</downerUserId>
    <loggedInStatus>{{profile_aspire_loggedin_status}}</loggedInStatus>
    <loggedInUserId>{{profile_user}}</loggedInUserId>
</div>
*/
function getAKCURLDetailsObject()
{
    var urlDiv = $("#AKCURLDetailsDivID")[0];
    var urlDivHtml = $(urlDiv).html();
    var urlDivXmlString = "<root>" + urlDivHtml + "</root>";
    var urlDivXmlObj = $.parseXML(urlDivXmlString);
    var urlDetailsJSONObject = AKC.getJSONAtNode(urlDivXmlObj, "root");
    //alert(JSON.stringify(urlDetailsJSONObject));
    return urlDetailsJSONObject;
}

/*
******************************************************
* Prime the pump
******************************************************
*/
    //Prime the pump
    $(document).ready(akcWidgetSetup);

})(); //eof-file


/*
******************************************************
* This has to stay outside the closure for now
* Future architecture may move this in
******************************************************
*/
function akcExpand_folderWidget_function(divObject)
{
    var urlDetailsObj = AKC.getAKCURLDetailsObject();
    if (urlDetailsObj.urlname == null)
    {
        alert("url not defined. weird error. this shouldn't happen");
        return;
    } 
    if (urlDetailsObj.urlname.toLowerCase() != "displaynoteimpurl")
    {
        //This is not the url I want to show this on
        return;
    }

    //Get the inner html of your div
    var expandDivData = $(divObject).html();
    dataxml = "<root>" + expandDivData + "</root>";
    dataxmlobj = $.parseXML(dataxml);
    var dataObj = AKC.getJSONAtNode(dataxmlobj,"root");
    var dataUrl = "/akc/display?url=NotesIMPTitlesURL"
    dataUrl += "&folderId=" + dataObj.folder_id + "&order_by_format=news&aspire_output_format=embedded-xml";
    var templateUrl =  "/akc/display?url=DisplayNoteBodyURL&reportId=4309";
    
    var folderWidget = new AKC.AkcWidget(dataUrl,templateUrl,divObject);
    //populate the folder widget
    folderWidget.populate();    
}