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
satya - Mon Oct 08 2012 22:51:58 GMT-0400 (Eastern Daylight Time)
ajax dom
ajax dom
satya - Mon Oct 08 2012 23:48:15 GMT-0400 (Eastern Daylight Time)
javascript array push method
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
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();
}