/*
* Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com
*
* http://extjs.com/license
*/
/**
* @class Ext.data.XmlReader
* @extends Ext.data.DataReader Data reader class to create an Array of
* {@link Ext.data.Record} objects from an XML document based on
* mappings in a provided Ext.data.Record constructor.
*
*
* Note that in order for the browser to parse a returned XML document, the Content-Type * header in the HTTP response must be set to "text/xml". *
* Example code: * *
* var Employee = Ext.data.Record.create([{
* name : 'name',
* mapping : 'name'
* }, // "mapping" property not needed if it's the same as "name"
* {
* name : 'occupation'
* } // This field will use "occupation" as the mapping.
* ]);
* var myReader = new Ext.data.XmlReader({
* totalRecords : "results", // The element which contains the total dataset size (optional)
* record : "row", // The repeated element which contains row information
* id : "id" // The element within the row that provides an ID for the record (optional)
* }, Employee);
*
*
* * This would consume an XML file like this: * *
* <?xml?>
* <dataset>
* <results>2</results>
* <row>
* <id>1</id>
* <name>Bill</name>
* <occupation>Gardener</occupation>
* </row>
* <row>
* <id>2</id>
* <name>Ben</name>
* <occupation>Horticulturalist</occupation>
* </row>
* </dataset>
*
*
* @cfg {String} totalRecords The DomQuery path from which to retrieve the total
* number of records in the dataset. This is only needed if the whole
* dataset is not passed in one go, but is being paged from the remote
* server.
* @cfg {String} record The DomQuery path to the repeated element which contains
* record information.
* @cfg {String} success The DomQuery path to the success attribute used by
* forms.
* @cfg {String} id The DomQuery path relative from the record element to the
* element that contains a record identifier value.
* @constructor Create a new XmlReader.
* @param {Object}
* meta Metadata configuration options
* @param {Object}
* recordType Either an Array of field definition objects as passed
* to {@link Ext.data.Record#create}, or a Record constructor object
* created using {@link Ext.data.Record#create}.
*/
Ext.data.XmlReader = function(meta, recordType) {
meta = meta || {};
Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType
|| meta.fields);
};
Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
/**
* This method is only used by a DataProxy which has retrieved data
* from a remote server.
*
* @param {Object}
* response The XHR object which contains the parsed XML
* document. The response is expected to contain a
* property called responseXML which refers to
* an XML document object.
* @return {Object} records A data block which is used by an
* {@link Ext.data.Store} as a cache of Ext.data.Records.
*/
read : function(response) {
var doc = response.responseXML;
if (!doc) {
throw {
message : "XmlReader.read: XML Document not available"
};
}
return this.readRecords(doc);
},
/**
* Create a data block containing Ext.data.Records from an XML
* document.
*
* @param {Object}
* doc A parsed XML document.
* @return {Object} records A data block which is used by an
* {@link Ext.data.Store} as a cache of Ext.data.Records.
*/
readRecords : function(doc) {
/**
* After any data loads/reads, the raw XML Document is available
* for further custom processing.
*
* @type XMLDocument
*/
this.xmlData = doc;
var root = doc.documentElement || doc;
var q = Ext.DomQuery;
var recordType = this.recordType, fields = recordType.prototype.fields;
var sid = this.meta.id;
var totalRecords = 0, success = true;
if (this.meta.totalRecords) {
totalRecords = q.selectNumber(this.meta.totalRecords, root,
0);
}
if (this.meta.success) {
var sv = q.selectValue(this.meta.success, root, true);
success = sv !== false && sv !== 'false';
}
var records = [];
var ns = q.select(this.meta.record, root);
for (var i = 0, len = ns.length; i < len; i++) {
var n = ns[i];
var values = {};
var id = sid ? q.selectValue(sid, n) : undefined;
for (var j = 0, jlen = fields.length; j < jlen; j++) {
var f = fields.items[j];
var v = q.selectValue(f.mapping || f.name, n,
f.defaultValue);
v = f.convert(v);
values[f.name] = v;
}
var record = new recordType(values, id);
record.node = n;
records[records.length] = record;
}
return {
success : success,
records : records,
totalRecords : totalRecords || records.length
};
}
});