"Sliced bread was the culmination of a century of technological innovation."
-- http://www.engineerguy.com/comm/4263.htm
Information, experience and learning of Steven Pothoven -- usually technology related.
"Sliced bread was the culmination of a century of technological innovation."
-- http://www.engineerguy.com/comm/4263.htm
Posted by
Steven Pothoven
at
11:00 AM
0
comments
responseXML
from an XMLHttpRequest
(XHR) or creates an empty DOM object for later manipulation.//
// XML
//
function XML(xmlDom) {
this.isIE = window.ActiveXObject;
if (xmlDom != null) {
this.xmlDom = xmlDom;
} else {
// create an empty document
if (this.isIE) {
Try.these (
function() { axDom = new ActiveXObject("MSXML2.DOMDocument.5.0"); },
function() { axDom = new ActiveXObject("MSXML2.DOMDocument.4.0"); },
function() { axDom = new ActiveXObject("MSXML2.DOMDocument.3.0"); },
function() { axDom = new ActiveXObject("MSXML2.DOMDocument"); },
function() { axDom = new ActiveXObject("Microsoft.XmlDom"); }
);
this.xmlDom = axDom;
} else {
this.xmlDom = document.implementation.createDocument("", "", null);
}
}
};
load
function to load an XML file from an URL.// load
//
// Loads an XML file from an URL
XML.prototype.load = function(url) {
this.xmlDom.async = false;
this.xmlDom.load(url);
};
getNode
function will do that for me.// getNode
//
// get a single node from the XML DOM using the XPath
XML.prototype.getNode = function(xpath) {
if (this.isIE) {
var result = this.xmlDom.selectSingleNode(xpath);
} else {
var evaluator = new XPathEvaluator();
var result = evaluator.evaluate(xpath, this.xmlDom, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
}
return result;
};
getNodeValue
a function to get the value of a node.// getNodeValue
//
// get the value of a the element specified by the XPath in the XML DOM
XML.prototype.getNodeValue = function(xpath) {
var value = null;
try {
var node = this.getNode(xpath);
if (this.isIE && node) {
value = node.text;
} else if (!this.isIE && node.singleNodeValue) {
value = node.singleNodeValue.textContent;
}
} catch (e) {}
return value;
};
getNodes
) and node values as an array (getNodeValues
).getNodeAsXml
function will do that for you. If you pass in the root XPath ("/") it will serialize the complete XML file. Also, the included prettyPrintXml
function can be used to escape the HTML characters.// getNodeAsXml
//
// get the XML contents of a node specified by the XPath
XML.prototype.getNodeAsXml = function(xpath) {
var str = null;
var aNode = this.getNode(xpath);
try {
if (this.isIE) {
str = aNode.xml;
} else {
var serializer = new XMLSerializer();
str = serializer.serializeToString(aNode.singleNodeValue);
}
} catch (e) {
str = "ERROR: No such node in XML";
}
return str;
};
updateNodeValue
), add new nodes/values (insertNode
), and delete existing nodes (removeNode
).// updateNodeValue
//
// update a specific element value in the XML DOM
XML.prototype.updateNodeValue = function(xpath, newvalue) {
var node = this.getNode(xpath);
var changeMade = false;
newvalue = newvalue.trim();
if (this.isIE && node) {
if (node.text != newvalue) {
node.text = newvalue;
changeMade = true;
}
} else if (!this.isIE && node.singleNodeValue) {
if (node.singleNodeValue.textContent != newvalue) {
node.singleNodeValue.textContent = newvalue;
changeMade = true;
}
} else {
if (newvalue.length > 0) {
this.insertNode(xpath);
changeMade = this.updateNodeValue(xpath, newvalue);
}
}
return changeMade;
};
// insertNode
//
// insert a new element (node) into the XML document based on the XPath
XML.prototype.insertNode = function(xpath) {
var xpathComponents = xpath.split("/");
var newChildName = xpathComponents.last();
var parentPath = xpath.substr(0, xpath.length - newChildName.length - 1);
var qualifierLoc = newChildName.indexOf("[");
// remove qualifier for node being added
if (qualifierLoc != -1) {
newChildName = newChildName.substr(0, qualifierLoc);
}
var node = this.getNode(parentPath);
var newChild = null;
if (this.isIE && node) {
newChild = this.xmlDom.createElement(newChildName);
node.appendChild(newChild);
} else if ((!this.isIE) && node.singleNodeValue) {
newChild = this.xmlDom.createElement(newChildName);
node.singleNodeValue.appendChild(newChild);
} else {
// add the parent, then re-try to add this child
var parentNode = this.insertNode(parentPath);
newChild = this.xmlDom.createElement(newChildName);
parentNode.appendChild(newChild);
}
return newChild;
};
// removeNode
//
// remove an element (node) from the XML document based on the xpath
XML.prototype.removeNode = function(xpath) {
var node = this.getNode(xpath);
var changed = false;
if (this.isIE && node) {
node.parentNode.removeChild(node);
changed = true;
} else if ((!this.isIE) && node.singleNodeValue) {
node.singleNodeValue.parentNode.removeChild(node.singleNodeValue);
changed = true;
}
return changed;
};
transform
function (including parameters).//
// XSLT Processor
//
function XSLT(xslUrl) {
this.isIE = window.ActiveXObject;
if (this.isIE) {
var xslDom = new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
xslDom.async = false;
xslDom.load(xslUrl);
if (xslDom.parseError.errorCode != 0) {
var strErrMsg = "Problem Parsing Style Sheet:\n" +
" Error #: " + xslDom.parseError.errorCode + "\n" +
" Description: " + xslDom.parseError.reason + "\n" +
" In file: " + xslDom.parseError.url + "\n" +
" Line #: " + xslDom.parseError.line + "\n" +
" Character # in line: " + xslDom.parseError.linepos + "\n" +
" Character # in file: " + xslDom.parseError.filepos + "\n" +
" Source line: " + xslDom.parseError.srcText;
alert(strErrMsg);
return false;
}
var xslTemplate = new ActiveXObject("MSXML2.XSLTemplate");
xslTemplate.stylesheet = xslDom;
this.xslProcessor = xslTemplate.createProcessor();
} else {
var xslDom = document.implementation.createDocument("", "", null);
xslDom.async = false;
xslDom.load(xslUrl);
this.xslProcessor = new XSLTProcessor();
this.xslProcessor.importStylesheet(xslDom);
}
};
transform
function will preform the XSL transformation and return the result. It accepts parameters to be passed to the XSL as an associative array of parameter name and value pairs.// transform
//
// Transform an XML document
XSLT.prototype.transform = function(xml, params) {
// set stylesheet parameters
for (var param in params) {
if (typeof params[param] != 'function') {
if (this.isIE) {
this.xslProcessor.addParameter(param, params[param]);
} else {
this.xslProcessor.setParameter(null, param, params[param]);
}
}
}
if (this.isIE) {
this.xslProcessor.input = xml.xmlDom;
this.xslProcessor.transform();
var output = this.xslProcessor.output;
} else {
var resultDOM = this.xslProcessor.transformToDocument(xml.xmlDom);
var serializer = new XMLSerializer();
var output = serializer.serializeToString(resultDOM);
}
return output;
};
xslProcessor = new XSLT(xslUrl);
// get the XML data
try {
var xmlData = new XML(request.responseXML);
} catch (e) {
alert(request.responseText);
}
// get the username out of the XML
var userName = xmlData.getNodeValue('//userName');
// transform the XML to some HTML content
var newData = xslProcessor.transform(xmlData, {'param':'value'});
document.getElementById('someDiv').innerHTML = newData;
/ Define a class variable which can be used to apply a style sheet to
// the XML for format it to HTML
XML.htmlFormatter = new XSLT("xsl/xmlverbatim.xsl");
// toHTML
//
// Transform the XML into formatted HTML
//
XML.prototype.toHTML = function() {
var html = null;
if (XML.htmlFormatter) {
html = XML.htmlFormatter.transform(this);
} else {
html = this.getNodeAsXml('/');
if (html != null) {
html = html.replace(/&/g, "&");
html = html.replace(/</g, "<");
html = html.replace(/>/g, "><br/>");
}
}
return html;
}
Posted by
Steven Pothoven
at
4:00 PM
8
comments
Labels: Ajax, javascript, SVG, web development, XML, XSL