| 
         
          // author: yangyi ([email protected]) 
           
           
          // Based on <http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247> (copy from ajaxslt) 
           
          var DOM_ELEMENT_NODE = 1; 
          var DOM_ATTRIBUTE_NODE = 2; 
          var DOM_TEXT_NODE = 3; 
          var DOM_CDATA_SECTION_NODE = 4; 
          var DOM_ENTITY_REFERENCE_NODE = 5; 
          var DOM_ENTITY_NODE = 6; 
          var DOM_PROCESSING_INSTRUCTION_NODE = 7; 
          var DOM_COMMENT_NODE = 8; 
          var DOM_DOCUMENT_NODE = 9; 
          var DOM_DOCUMENT_TYPE_NODE = 10; 
          var DOM_DOCUMENT_FRAGMENT_NODE = 11; 
          var DOM_NOTATION_NODE = 12; 
           
          /** 
           * http://developer.mozilla.org/en/docs/DOMParser 
           * 接受一段xml,解析成为xml document对象 
           * 调用时可用try{}catch(e){}捕捉错误,错误对象具有parser xml message属性 
           * @param {String} xml string 
           * @return {Object} xml document object 
           */ 
          function xmlDocument(/* String */xmlString){ 
              var doc = null; 
           
              if (window.ActiveXObject){ 
                  var ActiveIds = ['MSXML2.XMLDOM', 'Microsoft.XMLDOM', 'MSXML.XMLDOM', 'MSXML3.XMLDOM']; 
                  for (var len = ActiveIds.length, i = 0; i < len; i++){ 
                      var id = ActiveIds[i]; 
                      try{ 
                          var doc = new ActiveXObject(id); 
                          doc.async = false; 
                          doc.setProperty('SelectionLanguage', 'XPath'); 
                          doc.loadXML(xmlString); 
                          break; 
                      }catch (e){}finally{ 
                          if (doc && doc.parseError && doc.parseError.errorCode != 0){ 
                              throw {parser:'MSXML', message:doc.parseError.reason, xml:xmlString, func:'xmlDocument'}; 
                          } 
                      } 
                  } 
              }else if (typeof DOMParser != 'undefined'){ 
                  var parser = new DOMParser(); 
                  var doc = parser.parseFromString(xmlString, 'text/xml'); 
                  if (doc.documentElement.nodeName == 'parsererror'){ 
                      throw {parser:'DOMParser', message:doc.documentElement.firstChild.nodeValue, xml:xmlString, func:'xmlDocument'}; 
                  } 
              }else{ return false; } 
           
              return doc; 
          } 
           
          /** 
           * 获取指定节点或文档对象的xml内容 
           * port from ajaxslt xmlText() 
           * @param {Object} xml DOM Node or xml Document 
           * @return {String} xml string 
           */ 
          function xmlText(/* Document|Element */node){ 
              if (typeof node == 'string'){ return node; } 
           
              if (node.innerXML){ 
                  return node.innerXML; 
              }else if (node.xml){ 
                  return node.xml; 
              }else if (typeof XMLSerializer != 'undefined'){ 
                  return (new XMLSerializer()).serializeToString(node); 
              }else{ return false; } 
          } 
           
          /** 
           * 获取所有节点的内容 
           * port from ajaxslt xmlValue() 
           * @param {Object} xml DOM Node or xml Document 
           * @return {String} 
           */ 
          function xmlValue(/* Document|Element */node){ 
              var val = ''; 
              if (node.nodeType == DOM_TEXT_NODE || 
                  node.nodeType == DOM_CDATA_SECTION_NODE || 
                  node.nodeType == DOM_ATTRIBUTE_NODE){ 
                  val += node.nodeValue; 
              }else if (node.nodeType == DOM_ELEMENT_NODE || 
                        node.nodeType == DOM_DOCUMENT_NODE || 
                        node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE){ 
                  for (var len = node.childNodes.length, i = 0; i < len; i++){ 
                      val += arguments.callee(node.childNodes[i]); 
                  } 
              } 
              return val; 
          } 
           
          /** 
           * 获取节点属性,以对象形式返回 
           * @param {Object} 
           * @return {Object} 
           */ 
          function xmlGetAttributes(/* Element */node){ 
              var result = {}; 
              var nodeMap = node.attributes; 
              if (nodeMap){ 
                  for (var len = nodeMap.length, i = 0; i < len; i++){ 
                      var aNode = nodeMap.item(i); 
                      result[aNode.nodeName] = aNode.nodeValue; 
                  } 
              } 
              return result; 
          } 
           
          /** 
           * 设置节点属性 
           * @param {Object} xml DOM Node 
           * @param {Object} attribute data as object type 
           * @return {Void} 
           */ 
          function xmlSetAttributes(/* Element */node, /* Object */attributes){ 
              var attributes = attributes || {}; 
              for (key in attributes){ 
                  node.setAttribute(key, attributes[key]); 
              } 
          } 
           
          /** 
           * 使用xpath在xml树中查询 
           * http://developer.mozilla.org/en/docs/Introduction_to_using_XPath_in_JavaScript 
           * @param {Object} xml Document or xml DOM Node 
           * @param {String} xpath query string 
           * @param {Boolean} if set true, only return first result node 
           * @return {Mixed} return array include all nodes or first node 
           */ 
          function xpathSelectNodes(/* Document|Element */root, /* String */query, /* Boolean */returnFirst){ 
              if (window.ActiveXObject){ 
                  return returnFirst ? root.selectSingleNode(query) : root.selectNodes(query); 
              }else if (document.evaluate){ 
                  /** 
                   * DOMParser的return type有ordered和unordered两种 
                   * ordered会按照树中间的顺序排列结果,unordered不一定 
                   * 另外还有一种snapshots的,这种结果是树节点的一个clone 
                   * 也就是说,如果操作结果节点,原来的节点不会有改变 
                   * 这里使用非clone方式 
                   */ 
                  var returnType = returnFirst ? XPathResult.FIRST_ORDERED_NODE_TYPE : XPathResult.ORDERED_NODE_ITERATOR_TYPE; 
                  var doc = (root.nodeType == DOM_DOCUMENT_NODE) ? root : root.ownerDocument; 
                  var root = (root.nodeType == DOM_DOCUMENT_NODE) ? root.documentElement : root; 
                  var result = doc.evaluate(query, root, null, returnType, null); 
           
                  if (returnFirst){ 
                      var nodes = result.singleNodeValue; 
                  }else{ 
                      var nextNode = result.iterateNext(); 
                      var nodes = []; 
                      while (nextNode){ 
                          nodes.push(nextNode); 
                          nextNode = result.iterateNext(); 
                      } 
                  } 
              } 
              return nodes; 
          } 
           
          /** 
           * http://developer.mozilla.org/en/docs/Transforming_XML_with_XSLT 
           * http://developer.mozilla.org/en/docs/Using_the_Mozilla_JavaScript_interface_to_XSL_Transformations 
           * @param {Mixed} source xml, xml string or xml Document or xml DOM Node 
           * @param {Mixed} xslt style sheet, xml string or xml Document or xml DOM Node 
           * @param {Boolean} if set true, return processed xml as Document 
           * @return {Mixed} return string or Document 
           */ 
          function xsltProcess(/* String|Document|Element */srcDoc, /* String|Document|Element */stylesheet, /* Boolean */returnAsDoc){ 
              var returnAsDoc = (typeof returnAsDoc == 'undefined') ? false : returnAsDoc; 
              try{ 
                  var srcDoc = (typeof srcDoc == 'string') ? xmlDocument(srcDoc) : srcDoc; 
                  var stylesheet = (typeof stylesheet == 'string') ? xmlDocument(stylesheet) : stylesheet; 
              }catch(e){ e.func = 'xsltProcess'; throw e; } 
           
              if (typeof XSLTProcessor != 'undefined'){ 
                  var processor = new XSLTProcessor(); 
                  try{ 
                      processor.importStylesheet(stylesheet); 
                      var dest = processor.transformToDocument(srcDoc); 
                      return returnAsDoc ? dest : xmlText(dest); 
                  }catch(e){ throw {func:'xsltProcess', processor:'XSLTProcessor', xml:xmlText(srcDoc), xslt:xmlText(stylesheet)}; } 
              }else if (window.ActiveXObject){ 
                  try{ 
                      var dest = srcDoc.transformNode(stylesheet); 
                      return returnAsDoc ? xmlDocument(dest) : dest; 
                  }catch(e){ throw {func:'xsltProcess', processor:'MSXML', xml:xmlText(srcDoc), xslt:xmlText(stylesheet)}; } 
              } 
           
              return false; 
          } 
         
       |