Code coverage report for lib\xmlutil.js

Statements: 93.94% (31 / 33)      Branches: 75% (9 / 12)      Functions: 100% (5 / 5)      Lines: 93.94% (31 / 33)      Ignored: none     

All files » lib/ » xmlutil.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127                                            1 1 1   1             1                     1 90 90 90 420 310 310     310 310 310     90     1                       90                     3 3 3   3 7 3   7     3                     7                     13 13       13       1
/*
 * @copyright
 * Copyright © Microsoft Open Technologies, Inc.
 *
 * All Rights Reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http: *www.apache.org/licenses/LICENSE-2.0
 *
 * THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
 * ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
 * PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
 *
 * See the Apache License, Version 2.0 for the specific language
 * governing permissions and limitations under the License.
 */
'use strict';
 
var _ = require('underscore');
var select = require('xpath.js');
var XMLSerializer = require('xmldom').XMLSerializer;
 
var constants = require('./constants');
 
/**
 * @namespace XmlUtil
 * @private
 */
 
var XPATH_PATH_TEMPLATE = '*[local-name() = \'LOCAL_NAME\' and namespace-uri() = \'NAMESPACE\']';
/**
* The xpath implementation being used does not have a way of matching expanded namespace.
* This method takes an xpath query and expands all of the namespaces involved.  It then
* re-writes the query in to a longer form that directory matches the correct namespaces.
* @private
* @static
* @memberOf XmlUtil
* @param {string} xpath   The expath query string to expand.
* @returns {string} An expanded xpath query.
*/
function expandQNames(xpath) {
  var namespaces = constants.XmlNamespaces;
  var pathParts = xpath.split('/');
  for (var i=0; i < pathParts.length; i++) {
    if (pathParts[i].indexOf(':') !== -1) {
      var QNameParts = pathParts[i].split(':');
      Iif (QNameParts.length !== 2) {
        throw new Error('Unable to parse XPath string : ' + xpath + ' : with QName : ' + pathParts[i]);
      }
      var expandedPath = XPATH_PATH_TEMPLATE.replace('LOCAL_NAME', QNameParts[1]);
      expandedPath = expandedPath.replace('NAMESPACE', namespaces[QNameParts[0]]);
      pathParts[i] = expandedPath;
    }
  }
  return pathParts.join('/');
}
 
var exports = {
 
  /**
   * Performs an xpath select that does appropriate namespace matching since the imported
   * xpath module does not properly handle namespaces.
   * @static
   * @memberOf XmlUtil
   * @param  {object} dom     A dom object created by the xmldom module
   * @param  {string} xpath   An xpath expression
   * @return {array}          An array of matching dom nodes.
   */
  xpathSelect :  function (dom, xpath) {
    return select(dom, expandQNames(xpath));
  },
 
  /**
   * Given a dom node serializes all immediate children that are xml elements.
   * @static
   * @memberOf XmlUtil
   * @param  {object} node  An xml dom node.
   * @return {string}       Serialized xml.
   */
  serializeNodeChildren : function(node) {
    var doc = '';
    var sibling = node.firstChild;
    var serializer = new XMLSerializer();
 
    while (sibling) {
      if (this.isElementNode(sibling)) {
        doc += serializer.serializeToString(sibling);
      }
      sibling = sibling.nextSibling;
    }
 
    return doc !== '' ? doc : null;
  },
 
  /**
   * Detects whether the passed in dom node represents an xml element.
   * @static
   * @memberOf XmlUtil
   * @param  {object}  node   An xml dom node.
   * @return {Boolean}        true if the node represents an element.
   */
  isElementNode : function(node) {
    return _.has(node, 'tagName');
  },
 
  /**
   * Given an xmldom node this function returns any text data contained within.
   * @static
   * @memberOf XmlUtil
   * @param  {object} node  An xmldom node from which the data should be extracted.
   * @return {string}       Any data found within the element or null if none is found.
   */
  findElementText : function(node) {
    var sibling = node.firstChild;
    while (sibling && !sibling.data) {
      sibling = sibling.nextSibling;
    }
 
    return sibling.data ? sibling.data : null;
  }
};
 
module.exports = exports;