2013-08-01 60 views
2

我有一個搜索服務器,它提供了一個測試頁,我可以在其中輸入查詢,並以XML格式返回結果。我希望能夠以更加用戶友好的方式瀏覽結果,所以我開始使用XSLT,並且有一個簡單的樣式表,現在可以將不知何故的XML轉換爲僅顯示一些數據的簡單表格。這在我在本地執行時正常工作 - 即將XSL聲明添加到XML中,然後在Firefox等瀏覽器中打開XML。如何使用Greasemonkey腳本使用XSLT轉換XML文件?

我想要做的事情就是在我通過該測試頁面從服務器獲取結果後,立即在瀏覽器中應用此轉換。我調查了一下,發現it's possible to do this with javascript

然後我想到了可以動態地將JavaScript注入頁面的Greasemonkey userscripts。我只需要一個腳本,當我從測試頁面獲得XML結果時就會啓動它。然而,我卡在那裏,因爲它看起來像Greasemonkey不允許腳本在XML文件上運行(至少在Firefox中)。

我發現很少的例子,並試圖用它們作爲靈感,但不能使它們工作。 (Here's one, for example

這裏是我得到的XML的一個簡單的例子:

<?xml version="1.0" encoding="utf-8"?> 
<Results> 
    <Result> 
     <Listings total="2"> 
      <Res> 
       <Result index="0"> 
        <id>123456</id> 
        <name>My Business</name> 
        <category>Restaurants</category> 
        <phone>9872365</phone> 
       </Result> 
      </Res> 
      <Res> 
       <Result index="1"> 
        <id>876553</id> 
        <name>Some Other Business</name> 
        <category>Restaurants</category> 
        <phone>9834756</phone> 
       </Result> 
      </Res> 
     </Listings> 
    </Result> 
</Results> 

這裏是我加載中的Greasemonkey腳本 - 在那裏什麼也沒有發生:

// ==UserScript== 
// @name test xml renderer 
// @namespace http://sample.com 
// @description stylesheet for xml results 
// @include * 
// ==/UserScript== 

(function() { 
    var xsl_str = '<?xml version="1.0" encoding="utf-8"?>\n\ 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">\n\ 
    <xsl:output method="html"/>\n\ 
    <xsl:template match="/">\n\ 
     <html>\n\ 
      <head></head>\n\ 
      <body>\n\ 
       <table id="results" border="1" cellspacing="0" cellpadding="0">\n\ 
        <thead>\n\ 
         <tr>\n\ 
          <th class="name">id</th>\n\ 
          <th class="name">category ID</th>\n\ 
          <th class="name">name</th>\n\ 
          <th class="name">phone</th>\n\ 
         </tr>\n\ 
        </thead>\n\ 
        <tbody>\n\ 
         <xsl:for-each select="Results/Result/Listings/Res">\n\ 
          <tr>\n\ 
           <td class="small" width="120">\n\ 
            <xsl:value-of select="Result/id"/>\n\ 
           </td>\n\ 
           <td class="small" width="120">\n\ 
            <xsl:value-of select="Result/category"/>\n\ 
           </td>\n\ 
           <td class="small" width="120">\n\ 
            <xsl:value-of select="Result/name"/>\n\ 
           </td>\n\ 
           <td class="small" width="120">\n\ 
            <xsl:value-of select="Result/phone"/>\n\ 
           </td>\n\ 
          </tr>\n\ 
         </xsl:for-each>\n\ 
        </tbody>\n\ 
       </table>\n\ 
      </body>\n\ 
     </html>\n\ 
    </xsl:template>\n\ 
</xsl:stylesheet>\n\ 
'; 

    var processor = new XSLTProcessor(); 
    var dataXSL = new DOMParser().parseFromString(xsl_str, "text/xml"); 

    processor.importStylesheet(dataXSL); 
    dataXML = document; 
    var ownerDocument = document.implementation.createDocument("", "", null); 
    var newFragment = processor.transformToFragment(dataXML, ownerDocument); 
    dataXML.documentElement.replaceChild(newFragment, dataXML.documentElement.firstChild); 
})(); 

當我在Greasemonkey中啓用此腳本時,所有頁面都成功替換爲XSL模板中的上述HTML。然而,它似乎並不適用於本地XML文件或來自我的服務器的任何XML(我知道要使Greasemonkey在本地文件中工作,需要在Firefox中的about:config中更改設置 - extensions.greasemonkey.fileIsGreaseable)。

我沒有任何JavaScript經驗,所以最有可能我只是犯了一個非常基本的錯誤。以防萬一,所有的幫助真的很感激。

回答

1

該腳本正在努力或添加到document.head。你想用轉換的內容替換整個文檔。你可能通過將location.href更改爲適當構建的data: URL來實現。但整潔的做法是將替換爲整個document.documentElement

這個腳本在您的測試/示例XML文件:

// ==UserScript== 
// @name  _Test XML Renderer 
// @description stylesheet for xml results 
// @include  http://YOUR_SERVER.COM/YOUR_PATH/*.xml 
// @grant  none 
// ==/UserScript== 

var xsl_str = '<?xml version="1.0" encoding="utf-8"?>\n\ 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">\n\ 
    <xsl:output method="html"/>\n\ 
    <xsl:template match="/">\n\ 
     <html>\n\ 
      <head></head>\n\ 
      <body>\n\ 
       <table id="results" border="1" cellspacing="0" cellpadding="0">\n\ 
        <thead>\n\ 
         <tr>\n\ 
          <th class="name">id</th>\n\ 
          <th class="name">category ID</th>\n\ 
          <th class="name">name</th>\n\ 
          <th class="name">phone</th>\n\ 
         </tr>\n\ 
        </thead>\n\ 
        <tbody>\n\ 
         <xsl:for-each select="Results/Result/Listings/Res">\n\ 
          <tr>\n\ 
           <td class="small" width="120">\n\ 
            <xsl:value-of select="Result/id"/>\n\ 
           </td>\n\ 
           <td class="small" width="120">\n\ 
            <xsl:value-of select="Result/category"/>\n\ 
           </td>\n\ 
           <td class="small" width="120">\n\ 
            <xsl:value-of select="Result/name"/>\n\ 
           </td>\n\ 
           <td class="small" width="120">\n\ 
            <xsl:value-of select="Result/phone"/>\n\ 
           </td>\n\ 
          </tr>\n\ 
         </xsl:for-each>\n\ 
        </tbody>\n\ 
       </table>\n\ 
      </body>\n\ 
     </html>\n\ 
    </xsl:template>\n\ 
</xsl:stylesheet>\n\ 
'; 

var processor = new XSLTProcessor(); 
var dataXSL  = new DOMParser().parseFromString (xsl_str, "text/xml"); 

processor.importStylesheet (dataXSL); 

var newDoc  = processor.transformToDocument (document); 

//-- These next lines swap the new, processed doc in for the old one... 
window.content = newDoc; 

document.replaceChild (
    document.importNode (newDoc.documentElement, true), 
    document.documentElement 
); 
+0

就是這樣,現在就像一個魅力,非常感謝! – bergonzzi

+0

不客氣,樂意效勞! –

+0

我有一個關於在XSL模板中使用javascript的後續問題 - [將javascript添加到使用Greasemonkey腳本轉換爲XSLT的XML文件](http://stackoverflow.com/questions/18046191/adding-javascript-to -a-XML的文件轉化與 - 使用-A-Greasemonkey的-憑證XSLT的) – bergonzzi

0

我會在評論中加入這個,但我沒有相關的聲望。有兩件事我會檢查。尤其是如果這是從服務器就像你說的

  1. 確保你從服務器得到的是一個字符串,而不是一個對象
  2. 確保XML的一個字符串,而不是一個文件你從服務器獲得的信息是正確的。

如果你沒有得到一個字符串,你可以做一個Ajax請求從XML獲取文本。然後加載它作爲你的新的xml var。

如果你真的只想讓XML用戶友好的,我會建議您查看
http://code.google.com/p/vkbeautify

http://google-code-prettify.googlecode.com/svn/trunk/README.html

這些而風格化應該保持XML格式,以方便閱讀。另外,你不必亂用greasemonkey,而只能使用javascript。