1 /* 2 Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 /** 7 * @fileOverview Defines the {@link CKEDITOR.xml} class, which represents a 8 * loaded XML document. 9 */ 10 11 (function() 12 { 13 CKEDITOR.plugins.add( 'xml', {}); 14 15 /** 16 * Represents a loaded XML document. 17 * @constructor 18 * @param {object|string} xmlObjectOrData A native XML (DOM document) object or 19 * a string containing the XML definition to be loaded. 20 * @example 21 * var xml = <b>new CKEDITOR.xml( '<books><book title="My Book" /></books>' )</b>; 22 */ 23 CKEDITOR.xml = function( xmlObjectOrData ) 24 { 25 var baseXml = null; 26 27 if ( typeof xmlObjectOrData == 'object' ) 28 baseXml = xmlObjectOrData; 29 else 30 { 31 var data = ( xmlObjectOrData || '' ).replace( / /g, '\xA0' ); 32 if ( window.DOMParser ) 33 baseXml = (new DOMParser()).parseFromString( data, 'text/xml' ); 34 else if ( window.ActiveXObject ) 35 { 36 try { baseXml = new ActiveXObject( 'MSXML2.DOMDocument' ); } 37 catch(e) 38 { 39 try { baseXml = new ActiveXObject( 'Microsoft.XmlDom' ); } catch(e) {} 40 } 41 42 if ( baseXml ) 43 { 44 baseXml.async = false; 45 baseXml.resolveExternals = false; 46 baseXml.validateOnParse = false; 47 baseXml.loadXML( data ); 48 } 49 } 50 } 51 52 /** 53 * The native XML (DOM document) used by the class instance. 54 * @type object 55 * @example 56 */ 57 this.baseXml = baseXml; 58 }; 59 60 CKEDITOR.xml.prototype = 61 { 62 /** 63 * Get a single node from the XML document, based on a XPath query. 64 * @param {String} xpath The XPath query to execute. 65 * @param {Object} [contextNode] The XML DOM node to be used as the context 66 * for the XPath query. The document root is used by default. 67 * @returns {Object} A XML node element or null if the query has no results. 68 * @example 69 * // Create the XML instance. 70 * var xml = new CKEDITOR.xml( '<list><item id="test1" /><item id="test2" /></list>' ); 71 * // Get the first <item> node. 72 * var itemNode = <b>xml.selectSingleNode( 'list/item' )</b>; 73 * // Alert "item". 74 * alert( itemNode.nodeName ); 75 */ 76 selectSingleNode : function( xpath, contextNode ) 77 { 78 var baseXml = this.baseXml; 79 80 if ( contextNode || ( contextNode = baseXml ) ) 81 { 82 if ( CKEDITOR.env.ie || contextNode.selectSingleNode ) // IE 83 return contextNode.selectSingleNode( xpath ); 84 else if ( baseXml.evaluate ) // Others 85 { 86 var result = baseXml.evaluate( xpath, contextNode, null, 9, null); 87 return ( result && result.singleNodeValue ) || null; 88 } 89 } 90 91 return null; 92 }, 93 94 /** 95 * Gets a list node from the XML document, based on a XPath query. 96 * @param {String} xpath The XPath query to execute. 97 * @param {Object} [contextNode] The XML DOM node to be used as the context 98 * for the XPath query. The document root is used by default. 99 * @returns {ArrayLike} An array containing all matched nodes. The array will 100 * be empty if the query has no results. 101 * @example 102 * // Create the XML instance. 103 * var xml = new CKEDITOR.xml( '<list><item id="test1" /><item id="test2" /></list>' ); 104 * // Get the first <item> node. 105 * var itemNodes = xml.selectSingleNode( 'list/item' ); 106 * // Alert "item" twice, one for each <item>. 107 * for ( var i = 0 ; i < itemNodes.length ; i++ ) 108 * alert( itemNodes[i].nodeName ); 109 */ 110 selectNodes : function( xpath, contextNode ) 111 { 112 var baseXml = this.baseXml, 113 nodes = []; 114 115 if ( contextNode || ( contextNode = baseXml ) ) 116 { 117 if ( CKEDITOR.env.ie || contextNode.selectNodes ) // IE 118 return contextNode.selectNodes( xpath ); 119 else if ( baseXml.evaluate ) // Others 120 { 121 var result = baseXml.evaluate( xpath, contextNode, null, 5, null); 122 123 if ( result ) 124 { 125 var node; 126 while ( ( node = result.iterateNext() ) ) 127 nodes.push( node ); 128 } 129 } 130 } 131 132 return nodes; 133 }, 134 135 /** 136 * Gets the string representation of hte inner contents of a XML node, 137 * based on a XPath query. 138 * @param {String} xpath The XPath query to execute. 139 * @param {Object} [contextNode] The XML DOM node to be used as the context 140 * for the XPath query. The document root is used by default. 141 * @returns {String} The textual representation of the inner contents of 142 * the node or null if the query has no results. 143 * @example 144 * // Create the XML instance. 145 * var xml = new CKEDITOR.xml( '<list><item id="test1" /><item id="test2" /></list>' ); 146 * // Alert "<item id="test1" /><item id="test2" />". 147 * alert( xml.getInnerXml( 'list' ) ); 148 */ 149 getInnerXml : function( xpath, contextNode ) 150 { 151 var node = this.selectSingleNode( xpath, contextNode ), 152 xml = []; 153 if ( node ) 154 { 155 node = node.firstChild; 156 while ( node ) 157 { 158 if ( node.xml ) // IE 159 xml.push( node.xml ); 160 else if ( window.XMLSerializer ) // Others 161 xml.push( ( new XMLSerializer() ).serializeToString( node ) ); 162 163 node = node.nextSibling; 164 } 165 } 166 167 return xml.length ? xml.join( '' ) : null; 168 } 169 }; 170 })(); 171