Skip to content

Instantly share code, notes, and snippets.

@aek
Created January 31, 2012 20:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aek/1712702 to your computer and use it in GitHub Desktop.
Save aek/1712702 to your computer and use it in GitHub Desktop.
Parser for reading and writting XML formatted data
/*
---
name: Jx.Store.Parser.XML
description: Parser for reading and writting XML formatted data.
license: MIT-style license.
requires:
- Jx.Store.Parser
provides: [Jx.Store.Parser.XML]
...
*/
// $Id$
/**
* Class: Jx.Store.Parser.XML
*
* Extends: <Jx.Store.Parser>
*
* A Parser that handles encoding and decoding XML documents or strings
*
* License:
* Copyright (c) 2012, Ing. Axel Mendoza.
*
* This file is licensed under an MIT style license
*/
Jx.Store.Parser.XML = new Class({
Extends: Jx.Store.Parser,
Family: "Jx.Store.Parser.XML",
options: {
/**
* Option: xpath
* Set an xpath expression here to select the nodes you want to use for data retrieving
*/
xpath: null,
/**
* Option: rootNodeText
* Text of the root element in the generated xml string for encode function of this class
*/
rootNodeText: 'data',
/**
* Option: everyNodeText
* Text of every element under the root node in the generated xml string for encode function of this class
*/
everyNodeText: 'item'
},
/**
* APIMethod: parse
* Turns a XML string or document into a JSON object if possible.
*
* Parameters:
* data - the XML string or document representation of the data we're parsing
*/
parse: function (data) {
var self = this;
var type = Jx.type(data);
var xmlDoc = null;
if (type === 'string') {
if (window.DOMParser){
xmlDoc = new DOMParser().parseFromString(data,"text/xml");
}else{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(data);
}
} else{
xmlDoc = data;
}
xmlDoc = xmlDoc.documentElement;
if(this.options.xpath != null){
if (window.DOMParser){
var nodes = [];
try {
var results = document.evaluate(this.options.xpath, xmlDoc, null, XPathResult.ANY_TYPE, null);
var node;
while (node = results.iterateNext()){
nodes.push(node);
}
xmlDoc = {childNodes: nodes};
} catch (e) {
return null;
}
} else{
xmlDoc = {childNodes: xmlDoc.selectNodes(this.options.xpath)};
}
}
return this.getNodes(xmlDoc);
},
/**
* APIMethod: encode
* Takes an object and turns it into XML.
*
* Parameters:
* object - the object to encode
*/
encode: function (object) {
var data;
if (object instanceof Jx.Record) {
data = object.asObject();
} else {
data = object;
}
var xml = '<?xml version="1.0">';
xml+= '<'+this.options.rootNodeText+'>'+this.getStringNode(object, this.options.everyNodeText)+'</'+this.options.rootNodeText+'>';
return xml;
},
getStringNode: function(object, label){
var type = Jx.type(object);
var self = this;
var xml = '';
if(type == 'object'){
xml+='<'+label+'>';
for(var prop in object){
xml+=this.getStringNode(object[prop], prop);
}
xml+='</'+label+'>';
} else if(type == 'string'){
xml= '<'+label+'>'+object+'</'+label+'>';
} else if(type == 'array'){
Array.each(object, function(item){
xml+= self.getStringNode(item, label);
});
}
return xml;
},
getNodes: function(node){
if(node.childNodes.length != 0 && !(node.childNodes.length == 1 && node.childNodes[0].nodeType == 3)){
var data = [];
var self = this;
Array.each(node.childNodes, function(child){
var elem = {};
Array.each(child.attributes, function(attr){
elem[attr.name] = attr.value;
});
Array.each(child.childNodes, function(attr){
if(elem[attr.nodeName] != undefined){
if(Jx.type(elem[attr.nodeName]) == 'array'){
elem[attr.nodeName].push(self.getNodes(attr));
} else{
elem[attr.nodeName] = [elem[attr.nodeName]];
}
}else{
if(attr.nodeType == 3){
elem['value'] = attr.textContent;
} else{
elem[attr.nodeName] = self.getNodes(attr);
}
}
});
data.push(elem);
});
return data;
} else if(node.nodeType != 3 && node.attributes.length != 0){
data = {};
Array.each(node.attributes, function(attr){
data[attr.name] = attr.value;
});
data['value'] = node.textContent;
return data;
} else {
return node.textContent;
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment