2008-10-08 66 views
34

我正在尋找一個XPath庫來查詢FF,IE,Opera和Safari中的XML文檔......並找不到一個。你見過嗎?JavaScript中的跨瀏覽器XPath實現

+0

Федор,似乎你沒有閱讀張貼的答案?你有沒有找到合適的實現?歡呼聲 – 2008-12-03 03:41:41

回答

4

您可以使用基本的XPath plug-in for jQuery來獲取XPath查詢功能。

此外,您可以考慮閱讀本article on XPath XML processing(再次與jQuery的)

+1

謝謝!我看過兩個。用於jQuery的XPath插件只是將XPath表達式轉換爲jQuery選擇表達式。即使對於簡單的情況它也不起作用。 – 2008-10-08 15:42:28

+0

這是否工作在所有與jquery> 1.2? – 2010-02-16 18:22:10

+0

截至今日,這些libraties不可用。 – 2012-12-18 12:19:02

3

看看http://dev.abiss.gr/sarissa/項目。他們已經將大部分與XML相關的API遷移到IE中,以及評估文檔對象的方法。實際上,jQuery沒有XPath處理器,它有一個非常簡單的路徑選擇器,如:/ a/b/c只有

0

我不認爲它允許臨時查詢,但你可以看看Johann Burkard的XSLT jQuery plug-in以獲取有關如何實現XPath查詢的靈感。我使用它在我的jQuery Reference儀表板小部件中,它非常穩定。

5

Google's AJAXSLT開源項目符合規定的要求。

當作自己的描述去說:

「AJAXSLT是XSLT的的JavaScript的實現,因爲XSLT使用XPath,它也是的XPath的實現,可獨立使用XSLT的。這種實現的優點是它使得XSLT可以在更多的瀏覽器上統一使用,並且可以在本地提供,並且可以在必要時擴展到更多瀏覽器。 AJAXSLT對於積極爭取跨瀏覽器兼容其高級Web應用程序。 「

UPDATE:2010年底,Michael Kay一直在使用GWT將他的Saxon XSLT 2.0處理器編譯爲Javascript(從而使其可用於所有5個主流瀏覽器)。很快就會有一個瀏覽器輕量級的Saxon。

+0

截至2011年11月,Kay's Saxon的客戶端版本(CE)仍處於alpha版本。 – 2011-11-09 13:53:53

+0

@ james.garriss:這並不意味着它沒有被使用。本主題的xsl-list中有一些有趣的線索。我懷疑Saxonica的主要問題不是技術問題,而更多的是爲了尋找Saxon CE的正確商業模式,以便它可以盈利。 – 2011-11-09 14:05:46

0

您可以利用每個瀏覽器的現有原生DOM支持。爲此,您將不得不創建自己的包裝,原因是瀏覽器之間的差異。你可以看看http://dotnetcaffe.blogspot.com

問候

0

FormFaces(在JS XForms實現)具有可伊斯利提取並使用獨立可靠的XPath引擎。

0

我想你可以在這裏使用Cameron McCormack的xpath library。它完全爲我工作。

4

這是我用

// xpath.js 
// ------------------------------------------------------------------ 
// 
// a cross-browser xpath class. 
// Derived form code at http://jmvidal.cse.sc.edu/talks/javascriptxml/xpathexample.html. 
// 
// Tested in Chrome, IE9, and FF6.0.2 
// 
// Author  : Dino 
// Created : Sun Sep 18 18:39:58 2011 
// Last-saved : <2011-September-19 15:07:20> 
// 
// ------------------------------------------------------------------ 

/*jshint browser:true */ 

(function(globalScope) { 
    'use strict'; 

    /** 
    * The first argument to this constructor is the text of the XPath expression. 
    * 
    * If the expression uses any XML namespaces, the second argument must 
    * be a JavaScript object that maps namespace prefixes to the URLs that define 
    * those namespaces. The properties of this object are taken as prefixes, and 
    * the values associated to those properties are the URLs. 
    * 
    * There's no way to specify a non-null default XML namespace. You need to use 
    * prefixes in order to reference a non-null namespace in a query. 
    * 
    */ 

    var expr = function(xpathText, namespaces) { 
     var prefix; 
     this.xpathText = xpathText; // Save the text of the expression 
     this.namespaces = namespaces || null; // And the namespace mapping 

     if (document.createExpression) { 
      this.xpathExpr = true; 
      // I tried using a compiled xpath expression, it worked on Chrome, 
      // but it did not work on FF6.0.2. Threw various exceptions. 
      // So I punt on "compiling" the xpath and just evaluate it. 
      // 
      // This flag serves only to store the result of the check. 
      // 

       // document.createExpression(xpathText, 
       // // This function is passed a 
       // // namespace prefix and returns the URL. 
       // function(prefix) { 
       //  return namespaces[prefix]; 
       // }); 
     } 
     else { 
      // assume IE and convert the namespaces object into the 
      // textual form that IE requires. 
      this.namespaceString = ""; 
      if (namespaces !== null) { 
       for(prefix in namespaces) { 
        // Add a space if there is already something there 
        if (this.namespaceString.length>1) this.namespaceString += ' '; 
        // And add the namespace 
        this.namespaceString += 'xmlns:' + prefix + '="' + 
         namespaces[prefix] + '"'; 
       } 
      } 
     } 
    }; 

    /** 
    * This is the getNodes() method of XPath.Expression. It evaluates the 
    * XPath expression in the specified context. The context argument should 
    * be a Document or Element object. The return value is an array 
    * or array-like object containing the nodes that match the expression. 
    */ 
    expr.prototype.getNodes = function(xmlDomCtx) { 
     var self = this, a, i, 
      doc = xmlDomCtx.ownerDocument; 

     // If the context doesn't have ownerDocument, it is the Document 
     if (doc === null) doc = xmlDomCtx; 

     if (this.xpathExpr) { 
      // could not get a compiled XPathExpression to work in FF6 
      // var result = this.xpathExpr.evaluate(xmlDomCtx, 
      //  // This is the result type we want 
      //  XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, 
      //  null); 

      var result = doc.evaluate(this.xpathText, 
       xmlDomCtx, 
       function(prefix) { 
        return self.namespaces[prefix]; 
       }, 
       XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, 
       null); 

      // Copy the results into an array. 
      a = []; 
      for(i = 0; i < result.snapshotLength; i++) { 
       a.push(result.snapshotItem(i)); 
      } 
      return a; 
     } 
     else { 
      // evaluate the expression using the IE API. 
      try { 
       // This is IE-specific magic to specify prefix-to-URL mapping 
       doc.setProperty("SelectionLanguage", "XPath"); 
       doc.setProperty("SelectionNamespaces", this.namespaceString); 

       // In IE, the context must be an Element not a Document, 
       // so if context is a document, use documentElement instead 
       if (xmlDomCtx === doc) xmlDomCtx = doc.documentElement; 
       // Now use the IE method selectNodes() to evaluate the expression 
       return xmlDomCtx.selectNodes(this.xpathText); 
      } 
      catch(e2) { 
       throw "XPath is not supported by this browser."; 
      } 
     } 
    }; 


    /** 
    * This is the getNode() method of XPath.Expression. It evaluates the 
    * XPath expression in the specified context and returns a single matching 
    * node (or null if no node matches). If more than one node matches, 
    * this method returns the first one in the document. 
    * The implementation differs from getNodes() only in the return type. 
    */ 
    expr.prototype.getNode = function(xmlDomCtx) { 
     var self = this, 
       doc = xmlDomCtx.ownerDocument; 
     if (doc === null) doc = xmlDomCtx; 
     if (this.xpathExpr) { 

      // could not get compiled "XPathExpression" to work in FF4 
      // var result = 
      //  this.xpathExpr.evaluate(xmlDomCtx, 
      //  // We just want the first match 
      //  XPathResult.FIRST_ORDERED_NODE_TYPE, 
      //  null); 

      var result = doc.evaluate(this.xpathText, 
       xmlDomCtx, 
       function(prefix) { 
        return self.namespaces[prefix]; 
       }, 
       XPathResult.FIRST_ORDERED_NODE_TYPE, 
       null); 
      return result.singleNodeValue; 
     } 
     else { 
      try { 
       doc.setProperty("SelectionLanguage", "XPath"); 
       doc.setProperty("SelectionNamespaces", this.namespaceString); 
       if (xmlDomCtx == doc) xmlDomCtx = doc.documentElement; 
       return xmlDomCtx.selectSingleNode(this.xpathText); 
      } 
      catch(e) { 
       throw "XPath is not supported by this browser."; 
      } 
     } 
    }; 


    var getNodes = function(context, xpathExpr, namespaces) { 
     return (new globalScope.XPath.Expression(xpathExpr, namespaces)).getNodes(context); 
    }; 

    var getNode = function(context, xpathExpr, namespaces) { 
     return (new globalScope.XPath.Expression(xpathExpr, namespaces)).getNode(context); 
    }; 


    /** 
    * XPath is a global object, containing three members. The 
    * Expression member is a class modelling an Xpath expression. Use 
    * it like this: 
    * 
    * var xpath1 = new XPath.Expression("/kml/Document/Folder"); 
    * var nodeList = xpath1.getNodes(xmldoc); 
    * 
    * var xpath2 = new XPath.Expression("/a:kml/a:Document", 
    *         { a : 'http://www.opengis.net/kml/2.2' }); 
    * var node = xpath2.getNode(xmldoc); 
    * 
    * The getNodes() and getNode() methods are just utility methods for 
    * one-time use. Example: 
    * 
    * var oneNode = XPath.getNode(xmldoc, '/root/favorites'); 
    * 
    * var nodeList = XPath.getNodes(xmldoc, '/x:derp/x:twap', { x: 'urn:0190djksj-xx'}); 
    * 
    */ 

    // place XPath into the global scope. 
    globalScope.XPath = { 
     Expression : expr, 
     getNodes : getNodes, 
     getNode : getNode 
    }; 

}(this)); 
0

另一種選擇可能是(雖然似乎有點老)

2

這裏是在Javascript最近的跨瀏覽器實現的XPath: https://github.com/andrejpavlovic/xpathjs

它功能齊全,經過單元測試,並有很好的支持。最酷的部分是它也支持命名空間!