2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
8 YUI.add('dataschema-xml', function(Y) {
11 * Provides a DataSchema implementation which can be used to work with XML data.
14 * @submodule dataschema-xml
19 * XML subclass for the DataSchema Utility.
20 * @class DataSchema.XML
21 * @extends DataSchema.Base
26 /////////////////////////////////////////////////////////////////////////////
28 // DataSchema.XML static methods
30 /////////////////////////////////////////////////////////////////////////////
32 * Applies a given schema to given XML data.
35 * @param schema {Object} Schema to apply.
36 * @param data {XMLDoc} XML document.
37 * @return {Object} Schema-parsed data.
40 apply: function(schema, data) {
42 data_out = {results:[],meta:{}};
44 if(xmldoc && xmldoc.nodeType && (xmldoc.nodeType === 9 || xmldoc.nodeType === 1 || xmldoc.nodeType === 11) && schema) {
46 data_out = SchemaXML._parseResults(schema, xmldoc, data_out);
49 data_out = SchemaXML._parseMeta(schema.metaFields, xmldoc, data_out);
52 data_out.error = new Error("XML schema parse failure");
59 * Get an XPath-specified value for a given field from an XML node or document.
61 * @method _getLocationValue
62 * @param field {String | Object} Field definition.
63 * @param context {Object} XML node or document to search within.
64 * @return {Object} Data value or null.
68 _getLocationValue: function(field, context) {
69 var locator = field.locator || field.key || field,
70 xmldoc = context.ownerDocument || context,
71 result, res, value = null;
75 if(!LANG.isUndefined(xmldoc.evaluate)) {
76 result = xmldoc.evaluate(locator, context, xmldoc.createNSResolver(!context.ownerDocument ? context.documentElement : context.ownerDocument.documentElement), 0, null);
77 while(res = result.iterateNext()) {
78 value = res.textContent;
83 xmldoc.setProperty("SelectionLanguage", "XPath");
84 result = context.selectNodes(locator)[0];
85 value = result.value || result.text || null;
87 return Y.DataSchema.Base.parse(value, field);
95 * Parses results data according to schema
98 * @param xmldoc_in {Object} XML document parse.
99 * @param data_out {Object} In-progress schema-parsed data to update.
100 * @return {Object} Schema-parsed data.
104 _parseMeta: function(metaFields, xmldoc_in, data_out) {
105 if(LANG.isObject(metaFields)) {
107 xmldoc = xmldoc_in.ownerDocument || xmldoc_in;
109 for(key in metaFields) {
110 if (metaFields.hasOwnProperty(key)) {
111 data_out.meta[key] = SchemaXML._getLocationValue(metaFields[key], xmldoc);
119 * Schema-parsed list of results from full data
121 * @method _parseResults
122 * @param schema {Object} Schema to parse against.
123 * @param xmldoc_in {Object} XML document parse.
124 * @param data_out {Object} In-progress schema-parsed data to update.
125 * @return {Object} Schema-parsed data.
129 _parseResults: function(schema, xmldoc_in, data_out) {
130 if(schema.resultListLocator && LANG.isArray(schema.resultFields)) {
131 var nodeList = xmldoc_in.getElementsByTagName(schema.resultListLocator),
132 fields = schema.resultFields,
134 node, field, result, i, j;
136 if(nodeList.length) {
137 // Loop through each result node
138 for(i=nodeList.length-1; i>= 0; i--) {
142 // Find each field value
143 for(j=fields.length-1; j>= 0; j--) {
145 result[field.key || field] = SchemaXML._getLocationValue(field, node);
150 data_out.results = results;
153 data_out.error = new Error("XML schema result nodes retrieval failure");
160 Y.DataSchema.XML = Y.mix(SchemaXML, Y.DataSchema.Base);
164 }, '3.0.0' ,{requires:['dataschema-base']});