XSLTProcessor

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

XSLTProcessor 會將 XSLT 樣式錶轉換應用於 XML 文件,並生成一個新的 XML 文件作為輸出。它提供了載入 XSLT 樣式表、操作 <xsl:param> 引數值以及將轉換應用於文件的方法。

建構函式

XSLTProcessor()

建立一個新的 XSLTProcessor

例項方法

XSLTProcessor.importStylesheet()

匯入 XSLT 樣式表。如果提供的節點是文件節點,您可以傳入一個完整的 XSL 轉換或一個 字面量結果元素轉換;否則,它必須是 <xsl:stylesheet><xsl:transform> 元素。

XSLTProcessor.transformToFragment()

透過應用使用 XSLTProcessor.importStylesheet() 函式匯入的 XSLT 樣式表來轉換源節點。生成的文件片段的所有者文件是源節點。

XSLTProcessor.transformToDocument()

透過應用使用 XSLTProcessor.importStylesheet() 函式匯入的 XSLT 樣式表來轉換源節點。

XSLTProcessor.setParameter()

設定已匯入的 XSLT 樣式表中的引數(<xsl:param>)值。

XSLTProcessor.getParameter()

從 XSLT 樣式表中獲取引數的值。

XSLTProcessor.removeParameter()

如果引數之前已設定,則移除該引數。這將使 XSLTProcessor 使用 XSLT 樣式表中指定的引數的預設值。

XSLTProcessor.clearParameters()

XSLTProcessor 中移除所有已設定的引數。XSLTProcessor 隨後將使用 XSLT 樣式表中指定的預設值。

XSLTProcessor.reset()

XSLTProcessor 中移除所有引數和樣式表。

例項屬性

此介面沒有屬性。

示例

例項化 XSLTProcessor

js
async function init() {
  const parser = new DOMParser();
  const xsltProcessor = new XSLTProcessor();

  // Load the XSLT file, example1.xsl
  const xslResponse = await fetch("example1.xsl");
  const xslText = await xslResponse.text();
  const xslStylesheet = parser.parseFromString(xslText, "application/xml");
  xsltProcessor.importStylesheet(xslStylesheet);

  // process the file
  // …
}

基於文件 DOM 的一部分建立 XML 文件

對於實際轉換,XSLTProcessor 需要一個 XML 文件,該文件與匯入的 XSL 檔案結合使用以生成最終結果。XML 文件可以是使用 fetch() 載入的獨立 XML 檔案,也可以是現有頁面的一部分。

要處理頁面 DOM 的一部分,必須首先在記憶體中建立一個 XML 文件。假設要處理的 DOM 包含在一個 ID 為 example 的元素中,可以使用記憶體中 XML 文件的 Document.importNode() 方法來“克隆”該 DOM。 Document.importNode() 允許在文件之間傳輸 DOM 片段,在本例中是從 HTML 文件傳輸到 XML 文件。第一個引數引用要克隆的 DOM 節點。將第二個引數設定為“true”將克隆所有後代節點(深層克隆)。然後,可以使用 Node.appendChild() 將克隆的 DOM 插入到 XML 文件中,如下所示。

js
// Create a new XML document in memory
const xmlRef = document.implementation.createDocument("", "", null);

// We want to move a part of the DOM from an HTML document to an XML document.
// importNode is used to clone the nodes we want to process via XSLT - true makes it do a deep clone
const myNode = document.getElementById("example");
const clonedNode = xmlRef.importNode(myNode, true);

// Add the cloned DOM into the XML document
xmlRef.appendChild(clonedNode);

匯入樣式表後,XSLTProcessor 必須執行兩個方法才能進行實際轉換,即 XSLTProcessor.transformToDocument()XSLTProcessor.transformToFragment()XSLTProcessor.transformToDocument() 返回一個完整的 XML 文件,而 XSLTProcessor.transformToFragment() 返回一個文件片段,該片段可以輕鬆地新增到現有文件中。兩者都將要轉換的 XML 文件作為第一個引數。 XSLTProcessor.transformToFragment() 需要第二個引數,即生成片段的所有者文件物件。如果生成的片段將插入到當前 HTML 文件中,則傳遞 document 就足夠了。

從字串“XML Soup”建立 XML 文件

您可以使用 DOMParser 從 XML 字串建立 XML 文件。

js
const parser = new DOMParser();
const doc = parser.parseFromString(str, "text/xml");

執行轉換

js
const fragment = xsltProcessor.transformToFragment(xmlRef, document);

基本示例

基本示例將載入一個 XML 檔案並對其應用 XSL 轉換。這些是與 生成 HTML 示例中使用的相同檔案。XML 檔案描述了一篇文章,XSL 檔案格式化資訊以便顯示。

XML

xml
<?xml version="1.0"?>
<myNS:Article xmlns:myNS="http://devedge.netscape.com/2002/de">
  <myNS:Title>My Article</myNS:Title>
  <myNS:Authors>
    <myNS:Author company="Foopy Corp.">Mr. Foo</myNS:Author>
    <myNS:Author>Mr. Bar</myNS:Author>
  </myNS:Authors>
  <myNS:Body>
    The <b>rain</b> in <u>Spain</u> stays mainly in the plains.
  </myNS:Body>
</myNS:Article>

XSLT

xml
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                   xmlns:myNS="http://devedge.netscape.com/2002/de">

  <xsl:output method="html" />

  <xsl:template match="/">
    <html>

      <head>

        <title>
          <xsl:value-of select="/myNS:Article/myNS:Title"/>
        </title>

        <style>
          .myBox {margin:10px 155px 0 50px; border: 1px dotted #639ACE; padding:0 5px 0 5px;}
        </style>

      </head>

      <body>
        <p class="myBox">
          <span class="title">
            <xsl:value-of select="/myNS:Article/myNS:Title"/>
          </span> <br />

          Authors:   <br />
            <xsl:apply-templates select="/myNS:Article/myNS:Authors/myNS:Author"/>
          </p>

        <p class="myBox">
          <xsl:apply-templates select="//myNS:Body"/>
        </p>

      </body>

    </html>
  </xsl:template>

  <xsl:template match="myNS:Author">
     --   <xsl:value-of select="." />

    <xsl:if test="@company">
     ::   <b>  <xsl:value-of select="@company" />  </b>
    </xsl:if>

    <br />
  </xsl:template>

  <xsl:template match="myNS:Body">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

該示例將 .xsl (xslStylesheet) 和 .xml (xmlDoc) 檔案載入到記憶體中。然後匯入 .xsl 檔案 (xsltProcessor.importStylesheet(xslStylesheet)) 並執行轉換 (xsltProcessor.transformToFragment(xmlDoc, document))。這允許在頁面載入後獲取資料,而無需重新載入頁面。

JavaScript

js
async function init() {
  const parser = new DOMParser();
  const xsltProcessor = new XSLTProcessor();

  // Load the XSLT file, example1.xsl
  const xslResponse = await fetch("example1.xsl");
  const xslText = await xslResponse.text();
  const xslStylesheet = parser.parseFromString(xslText, "application/xml");
  xsltProcessor.importStylesheet(xslStylesheet);

  // Load the XML file, example1.xml
  const xmlResponse = await fetch("example1.xml");
  const xmlText = await xmlResponse.text();
  const xmlDoc = parser.parseFromString(xmlText, "application/xml");

  const fragment = xsltProcessor.transformToFragment(xmlDoc, document);

  document.getElementById("example").textContent = "";
  document.getElementById("example").appendChild(fragment);
}

init();

高階示例

這個高階示例根據內容對多個 div 進行排序。該示例允許多次排序內容,並在升序和降序之間交替。JavaScript 僅在第一次排序時載入 .xsl 檔案,並在檔案載入完成後將 xslLoaded 變數設定為 true。使用 XSLTProcessor.getParameter() 方法,程式碼可以確定是升序還是降序排序。如果引數為空(首次排序時,因為 XSLT 檔案中沒有該引數的值),則預設為升序。排序值使用 XSLTProcessor.setParameter() 設定。

XSLT 檔案中有一個名為 myOrder 的引數,JavaScript 會設定它來更改排序方法。xsl:sort 元素的 order 屬性可以使用 $myOrder 訪問引數的值。但是,該值需要是 XPath 表示式而不是字串,因此使用 {$myOrder}。使用 {} 會將內容評估為 XPath 表示式。

轉換完成後,結果會追加到文件中,如本示例所示。

XHTML

html
<div id="example">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
  <div>10</div>
</div>

JavaScript

js
let xslRef;
let xslLoaded = false;
const parser = new DOMParser();
const xsltProcessor = new XSLTProcessor();
let myDOM;

let xmlRef = document.implementation.createDocument("", "", null);

async function sort() {
  if (!xslLoaded) {
    const response = await fetch("example2.xsl");
    const xslText = await response.text();
    xslRef = parser.parseFromString(xslText, "application/xml");
    xsltProcessor.importStylesheet(xslRef);
    xslLoaded = true;
  }

  // Create a new XML document in memory
  xmlRef = document.implementation.createDocument("", "", null);

  // We want to move a part of the DOM from an HTML document to an XML document.
  // importNode is used to clone the nodes we want to process via XSLT - true makes it do a deep clone
  const myNode = document.getElementById("example");
  const clonedNode = xmlRef.importNode(myNode, true);

  // After cloning, we append
  xmlRef.appendChild(clonedNode);

  // Set the sorting parameter in the XSL file
  const sortVal = xsltProcessor.getParameter(null, "myOrder");

  if (sortVal === "" || sortVal === "descending") {
    xsltProcessor.setParameter(null, "myOrder", "ascending");
  } else {
    xsltProcessor.setParameter(null, "myOrder", "descending");
  }

  // Initiate the transformation
  const fragment = xsltProcessor.transformToFragment(xmlRef, document);

  // Clear the contents
  document.getElementById("example").textContent = "";

  myDOM = fragment;

  // Add the new content from the transformation
  document.getElementById("example").appendChild(fragment);
}

XSLT

xml
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" indent="yes" />

  <xsl:param name="myOrder" />

  <xsl:template match="/">

    <xsl:apply-templates select="/div//div">
      <xsl:sort select="." data-type="number" order="{$myOrder}" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="div">
    <xsl:copy-of select="." />
  </xsl:template>
</xsl:stylesheet>

規範

規範
DOM
# interface-xsltprocessor

瀏覽器相容性

另見