| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- /*
- * @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(':');
- if (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;
|