跳轉到內容

XQuery/XQuery 和 XSLT

來自 Wikibooks,開放世界中的開放書籍

您想建立一個執行 XSLT 轉換的 XML 文件的 RESTful Web 服務。

XQuery 在許多方面優於 XSLT。XQuery 被設計成一種簡短而簡潔的程式語言,它將 XML 和函式式語言語句交織在一起。因此,XQuery 程式通常比 XSLT 小得多。XQuery 處理器還被設計為使用索引,以便對大型資料集執行 XQuery 可以快速執行。但不幸的是,仍然有一些時候您必須使用 XSLT。其中一個例子是在瀏覽器中的轉換。eXist 資料庫附帶一個 XQuery 函式,允許您使用 XSLT 轉換 XML 檔案。

建立 XSLT 服務

[編輯 | 編輯原始碼]

eXist 包含一個函式來呼叫 XSLT 轉換,如下所示

  transform:transform($input as node()?, $stylesheet as item(), $params as node()?) node()?

其中

  $input is the node tree to be transformed
  $stylesheet  is either a URI or a node to be transformed.  If it is an URI, it can either point to an external 
   location or to an XSL stored in the db by using the 'xmldb:' scheme.
  $params are the optional XSLT name/value parameters with the following structure:
  <parameters>
     <param name="param-name1" value="param-value1"/>
  </parameters>

結果為零個或一個節點。轉換模組的名稱空間為 http://exist-db.org/xquery/transform

transform:transform() 函式可用於提供一項服務,該服務接受 XML 檔案的 URL、XSLT 指令碼的 URL 以及傳遞給樣式表的任何其他引數。

目前輸出為 text/html。

declare option exist:serialize "method=html media-type=text/html";

(: look for URL parameters for the XML file and the transform :)
let $xslt:= request:get-parameter("xslt",())
let $xml := request:get-parameter("xml",())

(: now get a list of all the URL parameters that are not either xml= or xslt= :)
let $params := 
<parameters>
   {for $p in request:parameter-names()
    let $val := request:get-parameter($p,())
    where  not($p = ("xml","xslt"))
    return
       <param name="{$p}"  value="{$val}"/>
   }
</parameters>

return 
  (: now run the transform :)
  transform:transform(doc($xml), doc($xslt), $params)

檢查 XSLT 版本

[編輯 | 編輯原始碼]

以下 XSLT 有助於檢查您正在執行的 XSLT 版本。

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
   <html>
      <body>
         <p>Version:
         <xsl:value-of select="system-property('xsl:version')" />
         <br />
         Vendor:
         <xsl:value-of select="system-property('xsl:vendor')" />
         <br />
         Vendor URL:
         <xsl:value-of select="system-property('xsl:vendor-url')" />
         </p>
      </body>
   </html>
</xsl:template>

</xsl:stylesheet>
[編輯 | 編輯原始碼]

在此示例中,一個主機上的 XML 檔案透過另一個主機上的 XSLT 指令碼進行轉換。XSLT 指令碼定義了一個表單,允許使用者選擇 XML 檔案中的條目子集,然後是搜尋結果(如果有)。

  1. 樣式表
  2. 資料
  3. 搜尋威士忌資料

序列圖描述了涉及的互動

序列圖

頁面抓取示例

[編輯 | 編輯原始碼]

參見 頁面抓取和雅虎天氣

使用 XSLT 匯入

[編輯 | 編輯原始碼]

XSLT 允許您呼叫匯入其他 XSLT 模板的公共庫的樣式表。但並非所有 XSLT 匯入路徑語句都可以在 eXist 中使用。在以下示例中,我們將使用一個匯入另一個樣式表的 XSLT 樣式表。以下假設您有一個名為 /db/test/xslt 的集合,並且所有檔案都放置在該集合中。

XQuery XSLT 測試程式

[編輯 | 編輯原始碼]
xquery version "1.0";
declare namespace transform="http://exist-db.org/xquery/transform";
declare option exist:serialize "method=xhtml media-type=text/html indent=yes";

let $input :=
<data>
   <element>element 1</element>
   <element>element 2</element>
   <element>element 3</element>
</data>

return
<html>
    <head>
       <title>Demonstration of running XSLT within an XQuery</title>
    </head>
    <body>  
        <h1>Demonstration of running XSLT within an XQuery</h1>
        { transform:transform($input, doc("/db/test/xslt/style.xsl"), ()) }  
    </body>  
</html>

頂級 Style.xsl

[編輯 | 編輯原始碼]
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:import href="common.xsl"/>
    <xsl:template match="/">
        <ol>
            <xsl:apply-templates/>
        </ol>
    </xsl:template>
</xsl:stylesheet>

在第二行,以下匯入按預期工作

   <xsl:import href="common.xsl"/>
   <xsl:import href="common.xsl" xml:base="https:///exist/rest/db/test/xslt"/>
   <xsl:import href="common.xsl" xml:base="/exist/rest/db/test/xslt"/>

但是您會注意到,使用以下內容無效

   <xsl:import href="/exist/rest/db/test/xslt/common.xsl"/>

匯入的 common.xsl

[編輯 | 編輯原始碼]
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="element">
    <li>
        <xsl:value-of select="."/>
    </li>
</xsl:template>

</xsl:stylesheet>

XForms 示例

[編輯 | 編輯原始碼]

您還可以建立一個簡單的 XForms 示例,作為該指令碼的前端。請參閱 XRX Wikibook 以獲取此 XForms 前端的示例。

xquery version "1.0";
declare option exist:serialize "method=xhtml media-type=text/xml indent=no process-xsl-pi=yes";
 
 (:
 transform:transform($node-tree as node()?, $stylesheet as item(), $parameters as node()?,  as xs:string) node()?
 :)

let $transform := 'https://:8080/exist/rest/db/xforms/xsltforms/xsltforms.xsl'

let $form :=
<html xmlns="http://www.w3.org/1999/xhtml" 
   xmlns:ev="http://www.w3.org/2001/xml-events" 
   xmlns:xf="http://www.w3.org/2002/xforms">
    <head>
      <title>XForms Template</title>
      <xf:model>
         <xf:instance xmlns="" id="save-data">
            <data>
               <name>John Smith</name>
            </data>
        </xf:instance>
      </xf:model>
   </head>
   <body>
      <h1>XForms Test Program</h1>
      <xf:input ref="name">
         <xf:label>Name: </xf:label>
      </xf:input>
   </body>
</html>

let $serialization-options := 'method=xml media-type=text/xml omit-xml-declaration=yes indent=no'

let $params := 
<parameters>
   <param name="output.omit-xml-declaration" value="yes"/>
   <param name="output.indent" value="no"/>
   <param name="output.media-type" value="text/html"/>
   <param name="output.method" value="xhtml"/>
</parameters>

return 
   transform:transform($form, $transform, $params, $serialization-options)

快取管理

[編輯 | 編輯原始碼]

預設情況下,一旦文件完成轉換,它就會駐留在快取中。如果檔案需要重新轉換,這對於效能原因來說非常有用,但有時如果原始檔發生變化,則需要重新執行轉換。

您可以透過更改配置檔案來停用快取。在 conf.xml 檔案中,將 @caching 值從 yes 更改為 no。

   <transformer  class="org.apache.xalan.processor.TransformerFactoryImpl" caching="no"/>

http://demo.exist-db.org/exist/xquery.xml#N10375

華夏公益教科書