Created
January 31, 2012 20:27
-
-
Save aek/1712702 to your computer and use it in GitHub Desktop.
Parser for reading and writting XML formatted data
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
--- | |
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