dataschema-xml.js revision 0d6d1a2d994933a68a100ec3dcdc7c7a0eeeae6c
985N/AYUI.add('dataschema-xml', function(Y) {
985N/A
985N/A/**
985N/A * The DataSchema utility provides a common configurable interface for widgets to
985N/A * apply a given schema to a variety of data.
985N/A *
985N/A * @module dataschema
985N/A */
985N/Avar LANG = Y.Lang,
985N/A
985N/A/**
985N/A * XML subclass for the YUI DataSchema utility.
985N/A * @class DataSchema.XML
985N/A * @extends DataSchema.Base
985N/A * @static
985N/A */
985N/ASchemaXML = {
985N/A
985N/A /////////////////////////////////////////////////////////////////////////////
985N/A //
985N/A // DataSchema.XML static methods
985N/A //
985N/A /////////////////////////////////////////////////////////////////////////////
985N/A /**
985N/A * Returns string name.
985N/A *
985N/A * @method toString
985N/A * @return {String} String representation for this object.
985N/A */
985N/A toString: function() {
985N/A return "DataSchema.XML";
985N/A },
985N/A
985N/A /**
985N/A * Applies a given schema to given XML data.
985N/A *
985N/A * @method apply
985N/A * @param schema {Object} Schema to apply.
985N/A * @param data {XMLDoc} XML document.
985N/A * @return {Object} Schema-parsed data.
985N/A * @static
985N/A */
985N/A apply: function(schema, data) {
985N/A var data_in = data,
985N/A data_out = {results:[],meta:{}};
985N/A
985N/A if(LANG.isObject(data_in) && schema) {
985N/A // Parse results data
985N/A if(!LANG.isUndefined(schema.resultsLocator)) {
985N/A data_out = SchemaXML._parseResults(schema, data_in, data_out);
985N/A }
985N/A
985N/A // Parse meta data
985N/A if(!LANG.isUndefined(schema.metaFields)) {
985N/A data_out = SchemaXML._parseMeta(schema.metaFields, data_in, data_out);
985N/A }
985N/A }
985N/A else {
985N/A data_out.error = true;
985N/A }
985N/A
985N/A return data_out;
985N/A },
985N/A
985N/A /**
985N/A * Schema-parsed list of results from full data
985N/A *
985N/A * @method _parseResults
985N/A * @param schema {Object} Schema to parse against.
985N/A * @param data_in {Object} Data to parse.
985N/A * @param data_out {Object} In-progress parsed data to update.
985N/A * @return {Object} Parsed data object.
985N/A * @static
985N/A * @protected
985N/A */
985N/A _parseResults: function(schema, data_in, data_out) {
985N/A var results = [],
985N/A nodeList,
985N/A error;
985N/A
985N/A if(schema.resultsLocator) {
985N/A nodeList = data_in.getElementsByTagName(schema.resultsLocator);
985N/A //if(xmlList) {
985N/A if(LANG.isArray(schema.resultsFields) && nodeList.length) {
985N/A data_out = SchemaXML._getFieldValues(schema.resultsFields, nodeList, data_out);
985N/A }
985N/A else {
985N/A data_out.results = [];
985N/A data_out.error = new Error(this.toString() + " Fields retrieval failure");
985N/A }
985N/A //}
985N/A //else {
985N/A //error = new Error(this.toString() + " Results locator failure");
985N/A //}
985N/A
985N/A //if (error) {
985N/A //data_out.error = error;
985N/A //}
985N/A
985N/A }
985N/A return data_out;
985N/A },
985N/A
985N/A /**
985N/A * Get field data values out of nodelist of full results
985N/A *
985N/A * @method _getFieldValues
985N/A * @param fields {Array} Fields to find.
985N/A * @param data_in {Array} Results data to parse.
985N/A * @param data_out {Object} In-progress parsed data to update.
985N/A * @return {Object} Parsed data object.
* @static
* @protected
*/
_getFieldValues: function(fields, data_in, data_out) {
var results = [],
i = data_in.length-1,
j,
item, result_in, result_out, field, key, data, subnode, datapieces;
try {
// Loop through each result node
for(; i>= 0; i--) {
result_out = {};
result_in = data_in[i];
// Find each field value
j = fields.length-1;
for(; j>= 0; j--) {
field = fields[j];
key = (LANG.isValue(field.key)) ? field.key : field;
// Values may be held in an attribute...
if(result_in.attributes.getNamedItem(key)) {
data = result_in.attributes.getNamedItem(key).value;
}
// ...or in a node
else {
subnode = result_in.getElementsByTagName(key);
if(subnode && subnode.item(0)) {
item = subnode.item(0);
// For IE, then DOM...
data = (item) ? ((item.text) ? item.text : (item.textContent) ? item.textContent : null) : null;
// ...then fallback, but check for multiple child nodes
if(!data) {
datapieces = [];
for(var k=0, len=item.childNodes.length; k<len; k++) {
if(item.childNodes[k].nodeValue) {
datapieces[datapieces.length] = item.childNodes[k].nodeValue;
}
}
if(datapieces.length > 0) {
data = datapieces.join("");
}
}
}
}
// Safety net
if(data === null) {
data = "";
}
var parser = (typeof field.parser === 'function') ?
field.parser :
// TODO: implement shortcuts
null;//DS.Parser[field.parser+''];
if(parser) {
data = parser.call(this, data);
}
// Safety measure
if(data === undefined) {
data = null;
}
result_out[key] = data;
}
results[i] = result_out;
}
}
catch(e) {
data_out.error = new Error(this.toString() + " Fields retrieval failure");
}
data_out.results = results;
return data_out;
},
/**
* Parses results data according to schema
*
* @method _parseMeta
* @param data_out {Object} Data to parse.
* @param data_in {Object} In-progress parsed data to update.
* @return {Object} Schema-parsed meta data.
* @static
* @protected
*/
_parseMeta: function(metaFields, data_in, data_out) {
if(LANG.isObject(metaFields)) {
var key, path, value;
for(key in metaFields) {
if (metaFields.hasOwnProperty(key)) {
path = metaFields[key];
// Look for a node
value = data_in.getElementsByTagName(path)[0];
if (value) {
value = value.firstChild.nodeValue;
} else {
// Look for an attribute
value = data_in.attributes.getNamedItem(path);
if (value) {
value = value.value;
}
}
if (LANG.isValue(value)) {
data_out.meta[key] = value;
}
}
}
}
else {
data_out.error = new Error(this.toString() + " Meta retrieval failure");
}
return data_out;
}
};
Y.DataSchema.XML = Y.mix(SchemaXML, Y.DataSchema.Base);
}, '@VERSION@' ,{requires:['dataschema-base']});