/* Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ /** * @fileOverview Defines the {@link CKEDITOR.xml} class, which represents a * loaded XML document. */ /** * Represents a loaded XML document. * @constructor * @param {object|string} xmlObjectOrData A native XML (DOM document) object or * a string containing the XML definition to be loaded. * @example * var xml = new CKEDITOR.xml( '' ); */ CKEDITOR.xml = function( xmlObjectOrData ) { var baseXml = null; if ( typeof xmlObjectOrData == 'object' ) baseXml = xmlObjectOrData; else { var data = ( xmlObjectOrData || '' ).replace( / /g, '\xA0' ); if ( window.DOMParser ) baseXml = (new DOMParser()).parseFromString( data, 'text/xml' ); else if ( window.ActiveXObject ) { try { baseXml = new ActiveXObject( 'MSXML2.DOMDocument' ); } catch(e) { try { baseXml = new ActiveXObject( 'Microsoft.XmlDom' ); } catch(e) {} } if ( baseXml ) { baseXml.async = false; baseXml.resolveExternals = false; baseXml.validateOnParse = false; baseXml.loadXML( data ); } } } /** * The native XML (DOM document) used by the class instance. * @type object * @example */ this.baseXml = baseXml; }; CKEDITOR.xml.prototype = { /** * Get a single node from the XML document, based on a XPath query. * @param {String} xpath The XPath query to execute. * @param {Object} [contextNode] The XML DOM node to be used as the context * for the XPath query. The document root is used by default. * @returns {Object} A XML node element or null if the query has no results. * @example * // Create the XML instance. * var xml = new CKEDITOR.xml( '' ); * // Get the first node. * var itemNode = xml.selectSingleNode( 'list/item' ); * // Alert "item". * alert( itemNode.nodeName ); */ selectSingleNode : function( xpath, contextNode ) { var baseXml = this.baseXml; if ( contextNode || ( contextNode = baseXml ) ) { if ( CKEDITOR.env.ie || contextNode.selectSingleNode ) // IE return contextNode.selectSingleNode( xpath ); else if ( baseXml.evaluate ) // Others { var result = baseXml.evaluate( xpath, contextNode, null, 9, null); return ( result && result.singleNodeValue ) || null; } } return null; }, /** * Gets a list node from the XML document, based on a XPath query. * @param {String} xpath The XPath query to execute. * @param {Object} [contextNode] The XML DOM node to be used as the context * for the XPath query. The document root is used by default. * @returns {ArrayLike} An array containing all matched nodes. The array will * be empty if the query has no results. * @example * // Create the XML instance. * var xml = new CKEDITOR.xml( '' ); * // Get the first node. * var itemNodes = xml.selectSingleNode( 'list/item' ); * // Alert "item" twice, one for each . * for ( var i = 0 ; i < itemNodes.length ; i++ ) * alert( itemNodes[i].nodeName ); */ selectNodes : function( xpath, contextNode ) { var baseXml = this.baseXml, nodes = []; if ( contextNode || ( contextNode = baseXml ) ) { if ( CKEDITOR.env.ie || contextNode.selectNodes ) // IE return contextNode.selectNodes( xpath ); else if ( baseXml.evaluate ) // Others { var result = baseXml.evaluate( xpath, contextNode, null, 5, null); if ( result ) { var node; while( ( node = result.iterateNext() ) ) nodes.push( node ); } } } return nodes; }, /** * Gets the string representation of hte inner contents of a XML node, * based on a XPath query. * @param {String} xpath The XPath query to execute. * @param {Object} [contextNode] The XML DOM node to be used as the context * for the XPath query. The document root is used by default. * @returns {String} The textual representation of the inner contents of * the node or null if the query has no results. * @example * // Create the XML instance. * var xml = new CKEDITOR.xml( '' ); * // Alert "". * alert( xml.getInnerXml( 'list' ) ); */ getInnerXml : function( xpath, contextNode ) { var node = this.selectSingleNode( xpath, contextNode ), xml = []; if ( node ) { node = node.firstChild; while ( node ) { if ( node.xml ) // IE xml.push( node.xml ); else if ( window.XMLSerializer ) // Others xml.push( ( new XMLSerializer() ).serializeToString( node ) ); node = node.nextSibling; } } return xml.length ? xml.join( '' ) : null; } };