學習 XSLT:XML文件轉換的關鍵

小万哥丶發表於2024-04-09

XSL(eXtensible Stylesheet Language)是一種用於 XML 的樣式語言。

XSL(T) 語言

XSLT 是一種用於轉換 XML 文件的語言。

XPath 是一種用於在 XML 文件中導航的語言。

XQuery 是一種用於查詢 XML 文件的語言。

它始於 XSL

XSL 代表 EXtensible Stylesheet Language

CSS = HTML 的樣式表

HTML 使用預定義標籤。每個標籤的含義以及如何顯示已經被充分理解。

CSS 用於向 HTML 元素新增樣式。

XSL = XML 的樣式表

XML 不使用預定義標籤,因此每個標籤的含義並不是很清楚。

一個 <table> 元素可能表示 HTML 表格、一件傢俱或其他東西 - 瀏覽器不知道如何顯示它!

因此,XSL 描述了 XML 元素應如何顯示。

XSL - 不僅僅是樣式表語言

XSL 由四個部分組成:

  • XSLT - 用於轉換 XML 文件的語言
  • XPath - 用於在 XML 文件中導航的語言
  • XSL-FO - 用於格式化 XML 文件的語言(已於 2013 年停用)
  • XQuery - 用於查詢 XML 文件的語言

示例

<?xml version="1.0"?>

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

<xsl:template match="/">
  <html>
  <body>
    <h2>My CD Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Title</th>
        <th>Artist</th>
      </tr>
      <xsl:for-each select="catalog/cd">
        <tr>
          <td><xsl:value-of select="title"/></td>
          <td><xsl:value-of select="artist"/></td>
        </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

什麼是 XSLT

XSLT 代表 XSL Transformations

XSLT 是 XSL 中最重要的部分

XSLT 將 XML 文件轉換為另一個 XML 文件

XSLT 使用 XPath 在 XML 文件中導航

XSLT = XSL 轉換

XSLT 是 XSL 中最重要的部分。

XSLT 用於將 XML 文件轉換為另一個 XML 文件,或者由瀏覽器識別的其他型別的文件,如 HTML 和 XHTML。通常,XSLT 透過將每個 XML 元素轉換為(X)HTML 元素來實現此目的。

使用 XSLT,您可以向輸出檔案新增/刪除元素和屬性。您還可以重新排列和排序元素,執行測試並根據需要隱藏和顯示元素,以及進行更多操作。

描述轉換過程的一種常見方式是說,XSLT 將 XML 源樹轉換為 XML 結果樹。

XSLT 使用 XPath

XSLT 使用 XPath 在 XML 文件中查詢資訊。XPath 用於在 XML 文件中導航元素和屬性。

它是如何工作的

在轉換過程中,XSLT 使用 XPath 定義應與一個或多個預定義模板匹配的源文件的部分。當找到匹配時,XSLT 將源文件的匹配部分轉換為結果文件。

XSLT 瀏覽器支援

所有主要瀏覽器都支援 XSLT 和 XPath

正確的樣式表宣告

宣告文件為 XSL 樣式表的根元素是 <xsl:stylesheet><xsl:transform>

注意:<xsl:stylesheet><xsl:transform> 完全是同義詞,可以使用任一種

要訪問 XSLT 元素、屬性和特性,我們必須在文件頂部宣告 XSLT 名稱空間。

從原始 XML 文件開始

以下 XML 文件("cdcatalog.xml")轉換為 XHTML:

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
.
.
</catalog>

在瀏覽器中檢視 XML 檔案:開啟 XML 檔案(單擊下面的連結)- XML 文件將以帶顏色的根和子元素顯示。通常,元素左側會有一個箭頭或加號/減號符號,點選它可以展開或摺疊元素結構。提示:要檢視原始 XML 原始碼,請右鍵單擊 XML 檔案,然後選擇“檢視頁面原始碼”!

建立 XSL 樣式表

然後,您可以建立一個 XSL 樣式表("cdcatalog.xsl"),其中包含一個轉換模板

<?xml version="1.0" encoding="UTF-8
"?>

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

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th>Title</th>
      <th>Artist</th>
    </tr>
    <xsl:for-each select="catalog/cd">
    <tr>
      <td><xsl:value-of select="title"/></td>
      <td><xsl:value-of select="artist"/></td>
    </tr>
    </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

將 XSL 樣式錶連結到 XML 文件

將 XSL 樣式表引用新增到您的 XML 文件("cdcatalog.xml")中:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?>
<catalog>
  <cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
.
.
</catalog>

如果您的瀏覽器支援 XSLT,它將會將您的 XML 優雅地轉換為 XHTML

XSLT <xsl:template> 元素

一個 XSL 樣式表由一個或多個稱為模板的規則集組成。

模板包含在匹配指定節點時應用的規則。

<xsl:template> 元素

<xsl:template> 元素用於構建模板。

match 屬性用於將模板與 XML 元素關聯起來。match 屬性還可以用於為整個 XML 文件定義模板。match 屬性的值是一個 XPath 表示式(即 match="/" 定義整個文件)

示例

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

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th>Title</th>
      <th>Artist</th>
    </tr>
    <tr>
      <td>.</td>
      <td>.</td>
    </tr>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

示例解釋

由於 XSL 樣式表是一個 XML 文件,因此它始終以 XML 宣告開頭:<?xml version="1.0" encoding="UTF-8"?>

接下來的元素 <xsl:stylesheet> 定義了此文件是一個 XSLT 樣式表文件(連同版本號和 XSLT 名稱空間屬性)。

<xsl:template> 元素定義了一個模板。match="/" 屬性將模板與 XML 源文件的根關聯起來。

<xsl:template> 元素內部的內容定義了要寫入輸出的一些 HTML。

最後兩行定義了模板的結束和樣式表的結束。

這個示例的結果有點令人失望,因為沒有將任何資料從 XML 文件複製到輸出中。在下一章中,您將學習如何使用 <xsl:value-of> 元素從 XML 元素中選擇值。

XSLT <xsl:value-of> 元素

<xsl:value-of> 元素用於提取所選節點的值。

<xsl:value-of> 元素

<xsl:value-of> 元素可用於提取 XML 元素的值,並將其新增到轉換的輸出流中:

示例

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

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th>Title</th>
      <th>Artist</th>
    </tr>
    <tr>
      <td><xsl:value-of select="catalog/cd/title"/></td>
      <td><xsl:value-of select="catalog/cd/artist"/></td>
    </tr>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

示例解釋

注意:在上面的示例中,select 屬性包含一個 XPath 表示式。XPath 表示式的工作方式類似於導航檔案系統;斜槓 (/) 選擇子目錄。

上面示例的結果有點令人失望;只有一行資料從 XML 文件複製到輸出中。在下一章中,您將學習如何使用 <xsl:for-each> 元素迴圈遍歷 XML 元素,並顯示所有記錄。

XSLT <xsl:for-each> 元素

<xsl:for-each> 元素允許您在 XSLT 中進行迴圈。

<xsl:for-each> 元素

XSL <xsl:for-each> 元素可用於選擇指定節點集的每個 XML 元素:

示例

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

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th>Title</th>
      <th>Artist</th>
    </tr>
    <xsl:for-each select="catalog/cd">
    <tr>
      <td><xsl:value-of select="title"/></td>
      <td><xsl:value-of select="artist"/></td>
    </tr>
    </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

注意:select 屬性的值是一個 XPath 表示式。XPath 表示式的工作方式類似於導航檔案系統;斜槓 (/) 選擇子目錄。

篩選輸出

我們還可以透過向 <xsl:for-each> 元素的 select 屬性新增條件來對 XML 檔案中的輸出進行篩選。

<xsl:for-each select="catalog/cd[artist='Bob Dylan']">

合法的篩選運算子有:

  • =(等於)
  • !=(不等於)
  • <(小於)
  • >(大於)

看看調整後的 XSL 樣式表:

示例

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

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th>Title</th>
      <th>Artist</th>
    </tr>
    <xsl:for-each select="catalog/cd[artist='Bob Dylan']">
    <tr>
      <td><xsl:value-of select="title"/></td>
      <td><xsl:value-of select="artist"/></td>
    </tr>
    </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

XSLT <xsl:sort> 元素

<xsl:sort> 元素用於對輸出進行排序。

排序資訊放在哪裡

要對輸出進行排序,只需在 XSL 檔案的 <xsl:for-each> 元素內部新增一個 <xsl:sort> 元素:

示例

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

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th>Title</th>
      <th>Artist</th>
    </tr>
    <xsl:for-each select="catalog/cd">
      <xsl:sort select="artist"/>
      <tr>
        <td><xsl:value-of select="title"/></td>
        <td><xsl:value-of select="artist"/></td>
      </tr>
    </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

注意:select 屬性指示要排序的 XML 元素。

XSLT <xsl:if> 元素

<xsl:if> 元素用於根據 XML 檔案的內容進行條件測試。

<xsl:if> 元素

要對 XML 檔案的內容進行條件 if 測試,請將 <xsl:if> 元素新增到 XSL 文件中。

語法

<xsl:if test="expression">
  ... 如果表示式為真,則輸出一些內容...
</xsl:if>

<xsl:if> 元素放在哪裡

要新增條件測試,請在 XSL 檔案中的 <xsl:for-each> 元素內部新增 <xsl:if> 元素:

示例

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

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th>Title</th>
      <th>Artist</th>
      <th>Price</th>
    </tr>
    <xsl:for-each select="catalog/cd">
      <xsl:if test="price &gt; 10">
        <tr>
          <td><xsl:value-of select="title"/></td>
          <td><xsl:value-of select="artist"/></td>
          <td><xsl:value-of select="price"/></td>
        </tr>
      </xsl:if>
    </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

注意:所需 test 屬性的值包含要評估的表示式。

上面的程式碼只會輸出價格高於 10 的 CD 的標題和藝術家元素。

XSLT <xsl:choose> 元素

<xsl:choose> 元素與 <xsl:when><xsl:otherwise> 結合使用,用於表達多個條件測試。

<xsl:choose> 元素

語法

<xsl:choose>
  <xsl:when test="expression">
    ... 一些輸出 ...
  </xsl:when>
  <xsl:otherwise>
    ... 一些輸出 ....
  </xsl:otherwise>
</xsl:choose>

選擇條件的放置位置

要對 XML 檔案進行多個條件測試,請將 <xsl:choose><xsl:when><xsl:otherwise> 元素新增到 XSL 檔案中:

示例

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

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th>Title</th>
      <th>Artist</th>
    </tr>
    <xsl:for-each select="catalog/cd">
    <tr>
      <td><xsl:value-of select="title"/></td>
      <xsl:choose>
        <xsl:when test="price &gt; 10">
          <td bgcolor="#ff00ff">
          <xsl:value-of select="artist"/></td>
        </xsl:when>
        <xsl:otherwise>
          <td><xsl:value-of select="artist"/></td>
        </xsl:otherwise>
      </xsl:choose>
    </tr>
    </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

上述程式碼將在 CD 的價格高於 10 時,為“Artist”列新增粉色背景顏色。

另一個示例

以下是包含兩個 <xsl:when> 元素的另一個示例:

示例

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

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th>Title</th>
      <th>Artist</th>
    </tr>
    <xsl:for-each select="catalog/cd">
    <tr>
      <td><xsl:value-of select="title"/></td>
      <xsl:choose>
        <xsl:when test="price &gt; 10">
          <td bgcolor="#ff00ff">
          <xsl:value-of select="artist"/></td>
        </xsl:when>
        <xsl:when test="price &gt; 9">
          <td bgcolor="#cccccc">
          <xsl:value-of select="artist"/></td>
        </xsl:when>
        <xsl:otherwise>
          <td><xsl:value-of select="artist"/></td>
        </xsl:otherwise>
      </xsl:choose>
    </tr>
    </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

上述程式碼將在 CD 的價格高於 10 時為“Artist”列新增粉色背景顏色,並在 CD 的價格高於 9 且低於或等於 10 時為其新增灰色背景顏色。

XSLT <xsl:apply-templates> 元素

<xsl:apply-templates> 元素將一個模板規則應用於當前元素或當前元素的子節點。

<xsl:apply-templates> 元素將一個模板應用於當前元素或當前元素的子節點。

如果我們給 <xsl:apply-templates> 元素新增一個 "select" 屬性,它將僅處理與屬性值匹配的子元素。我們可以使用 "select" 屬性來指定子節點的處理順序。

請看下面的 XSL 樣式表:

示例

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

<xsl:template match="/">
  <html>
  <body>
  <h2>My CD Collection</h2>
  <xsl:apply-templates/>
  </body>
  </html>
</xsl:template>

<xsl:template match="cd">
  <p>
  <xsl:apply-templates select="title"/>
  <xsl:apply-templates select="artist"/>
  </p>
</xsl:template>

<xsl:template match="title">
  Title: <span style="color:#ff0000">
  <xsl:value-of select="."/></span>
  <br />
</xsl:template>

<xsl:template match="artist">
  Artist: <span style="color:#00ff00">
  <xsl:value-of select="."/></span>
  <br />
</xsl:template>

</xsl:stylesheet>

XSLT - 在客戶端

XSLT 可以用於在您的瀏覽器中將文件轉換為 XHTML。透過向 XML 檔案新增 XSL 樣式表並讓瀏覽器執行轉換來實現這一點。即使這種方法執行良好,但並不總是希望在 XML 檔案中包含樣式表引用(例如,在非 XSLT 感知的瀏覽器中無法工作)。

一個更加靈活的解決方案是使用 JavaScript 來進行轉換。

透過使用 JavaScript,我們可以:

  • 進行瀏覽器特定的測試
  • 根據瀏覽器和使用者需求使用不同的樣式表

這就是 XSLT 的美妙之處!XSLT 的一個設計目標是使其能夠將資料從一種格式轉換為另一種格式,支援不同的瀏覽器和不同的使用者需求。

XML 檔案和 XSL 檔案

檢視您在前幾章中看到的 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
.
.
</catalog>

檢視 XML 檔案

<?xml version="1.0" encoding="UTF-8"?>

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

<xsl:template match="/">
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th style="text-align:left">Title</th>
      <th style="text-align:left">Artist</th>
    </tr>
    <xsl:for-each select="catalog/cd">
    <tr>
      <td><xsl:value-of select="title" /></td>
      <td><xsl:value-of select="artist" /></td>
    </tr>
    </xsl:for-each>
  </table>
</xsl:template>

</xsl:stylesheet>

在瀏覽器中將 XML 轉換為 XHTML

以下是在客戶端將 XML 檔案轉換為 XHTML 所需的原始碼:

示例

<!DOCTYPE html>
<html>
<head>
<script>
function loadXMLDoc(filename)
{
if (window.ActiveXObject)
  {
  xhttp = new ActiveXObject("Msxml2.XMLHTTP");
  }
else
  {
  xhttp = new XMLHttpRequest();
  }
xhttp.open("GET", filename, false);
try {xhttp.responseType = "msxml-document"} catch(err) {}
xhttp.send("");
return xhttp.responseXML;
}

function displayResult()
{
xml = loadXMLDoc("cdcatalog.xml");
xsl = loadXMLDoc("cdcatalog.xsl");
// IE 瀏覽器的程式碼
if (window.ActiveXObject || xhttp.responseType == "msxml-document")
  {
  ex = xml.transformNode(xsl);
  document.getElementById("example").innerHTML = ex;
  }
// Chrome、Firefox、Opera 等其他瀏覽器的程式碼
else if (document.implementation && document.implementation.createDocument)
  {
  xsltProcessor = new XSLTProcessor();
  xsltProcessor.importStylesheet(xsl);
  resultDocument = xsltProcessor.transformToFragment(xml, document);
  document.getElementById("example").appendChild(resultDocument);
  }
}
</script>
</head>
<body onload="displayResult()">
<div id="example" />
</body>
</html>

示例解釋

loadXMLDoc() 函式執行以下操作:

  • 建立一個 XMLHttpRequest 物件
  • 使用 XMLHttpRequest 物件的 open() 和 send() 方法向伺服器傳送請求
  • 獲取響應資料作為 XML 資料

displayResult() 函式用於顯示由 XSL 檔案樣式化的 XML 檔案:

  • 載入 XML 和 XSL 檔案
  • 測試使用者使用的瀏覽器型別
  • 如果是 Internet Explorer:
    • 使用 transformNode() 方法將 XSL 樣式表應用於 xml 文件
    • 將當前文件的 body(id="example")設定為包含樣式化的 xml 文件
  • 如果是其他瀏覽器:
    • 建立一個新的 XSLTProcessor 物件並將 XSL 檔案匯入其中
    • 使用 transformToFragment() 方法將 XSL 樣式表應用於 xml 文件
    • 將當前文件的 body(id="example")設定為包含樣式化的 xml 文件

XSLT - 在伺服器端

為了使 XML 資料對所有型別的瀏覽器都可用,我們可以在伺服器上轉換 XML 文件,並將其作為 XHTML 傳送回瀏覽器。

一個跨瀏覽器解決方案

在前一章中,我們解釋瞭如何使用 XSLT 在瀏覽器中將文件從 XML 轉換為 XHTML。我們使用了 JavaScript 和 XML 解析器進行轉換。但是,在沒有 XML 解析器的瀏覽器中,這種方法將無法工作。

為了使 XML 資料對所有型別的瀏覽器都可用,我們可以在伺服器上轉換 XML 文件,並作為 XHTML 傳送回瀏覽器。

這是 XSLT 的另一個美妙之處。XSLT 的一個設計目標是使其能夠在伺服器上將資料從一種格式轉換為另一種格式,向所有型別的瀏覽器返回可讀資料。

XML 檔案和 XSLT 檔案

檢視您在前幾章中看到的 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
.
.
</catalog>

檢視 XML 檔案

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

<xsl:template match="/">
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th style="text-align:left">Title</th>
      <th style="text-align:left">Artist</th>
    </tr>
    <xsl:for-each select="catalog/cd">
    <tr>
      <td><xsl:value-of select="title" /></td>
      <td><xsl:value-of select="artist" /></td>
    </tr>
    </xsl:for-each>
  </table>
</xsl:template>

</xsl:stylesheet>

以下是在伺服器上將 XML 檔案轉換為 XHTML 所需的 PHP 原始碼

<?php
// 載入 XML 檔案
$xml = new DOMDocument;
$xml->load('cdcatalog.xml');

// 載入 XSL 檔案
$xsl = new DOMDocument;
$xsl->load('cdcatalog.xsl');

// 配置轉換器
$proc = new XSLTProcessor;

// 附加 xsl 規則
$proc->importStyleSheet($xsl);

echo $proc->transformToXML($xml);
?>

以下是在伺服器上將 XML 檔案轉換為 XHTML 所需的 ASP 原始碼

<%
'載入 XML 檔案
set xml = Server.CreateObject("Microsoft.XMLDOM")
xml.async = false
xml.load(Server.MapPath("cdcatalog.xml"))

'載入 XSL 檔案
set xsl = Server.CreateObject("Microsoft.XMLDOM")
xsl.async = false
xsl.load(Server.MapPath("cdcatalog.xsl"))

'轉換檔案
Response.Write(xml.transformNode(xsl))
%>

XSLT - 編輯 XML

儲存在 XML 檔案中的資料可以從 Internet 瀏覽器中進行編輯。

開啟、編輯和儲存 XML

現在,我們將展示如何開啟、編輯和儲存儲存在伺服器上的 XML 檔案。

我們將使用 XSL 來將 XML 文件轉換為 HTML 表單。 XML 元素的值將寫入 HTML 表單中的 HTML 輸入欄位中。 HTML 表單是可編輯的。 編輯資料後,資料將被提交回伺服器,XML 檔案將被更新(我們將顯示 PHP 和 ASP 的程式碼)。

XML 檔案和 XSL 檔案

首先,看一下 XML 文件("tool.xml"):

<?xml version="1.0" encoding="UTF-8"?>
<tool>
  <field id="prodName">
    <value>HAMMER HG2606</value>
  </field>
  <field id="prodNo">
    <value>32456240</value>
  </field>
  <field id="price">
    <value>$30.00</value>
  </field>
</tool>

然後,看一下以下樣式表("tool.xsl")

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

<xsl:template match="/">
  <html>
  <body>
  <form method="post" action="edittool.asp">
  <h2>工具資訊(編輯):</h2>
  <table border="0">
    <xsl:for-each select="tool/field">
    <tr>
      <td><xsl:value-of select="@id"/></td>
      <td>
      <input type="text">
      <xsl:attribute name="id">
        <xsl:value-of select="@id" />
      </xsl:attribute>
      <xsl:attribute name="name">
        <xsl:value-of select="@id" />
      </xsl:attribute>
      <xsl:attribute name="value">
        <xsl:value-of select="value" />
      </xsl:attribute>
      </input>
      </td>
    </tr>
    </xsl:for-each>
  </table>
  <br />
  <input type="submit" id="btn_sub" name="btn_sub" value="Submit" />
  <input type="reset" id="btn_res" name="btn_res" value="Reset" />
  </form>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

上面的 XSL 檔案迴圈遍歷 XML 檔案中的元素,併為每個 XML "field" 元素建立一個輸入欄位。 XML "field" 元素的 "id" 屬性的值被新增到每個 HTML 輸入欄位的 "id" 和 "name" 屬性中。 每個 XML "value" 元素的值被新增到每個 HTML 輸入欄位的 "value" 屬性中。 結果是一個可編輯的 HTML 表單,其中包含來自 XML 檔案的值。

然後,我們有第二個樣式表:"tool_updated.xsl"。 這是將用於顯示更新的 XML 資料的 XSL 檔案。 這個樣式表不會導致可編輯的 HTML 表單,而是靜態的 HTML 表:

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

<xsl:template match="/">
  <html>
  <body>
  <h2>更新的工具資訊:</h2>
  <table border="1">
    <xsl:for-each select="tool/field">
    <tr>
      <td><xsl:value-of select="@id" /></td>
      <td><xsl:value-of select="value" /></td>
    </tr>
    </xsl:for-each>
  </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

在上面的 "tool.xsl" 檔案中,將 HTML 表單的 action 屬性更改為 "edittool.php"。

"edittool.php" 頁面包含兩個函式:loadFile() 函式載入和轉換 XML 檔案以供顯示,updateFile() 函式將更改應用於 XML 檔案:

<?php
function loadFile($xml, $xsl)
{
$xmlDoc = new DOMDocument();
$xml

Doc->load($xml);

$xslDoc = new DOMDocument();
$xslDoc->load($xsl);

$proc = new XSLTProcessor();
$proc->importStyleSheet($xslDoc);
echo $proc->transformToXML($xmlDoc);
}

function updateFile($xml)
{
$xmlLoad = simplexml_load_file($xml);
$postKeys = array_keys($_POST);

foreach($xmlLoad->children() as $x)
{
  foreach($_POST as $key=>$value)
  {
    if($key == $x->attributes())
    {
      $x->value = $value;
    }
  }
}

$xmlLoad->asXML($xml);
loadFile($xml,"tool_updated.xsl");
}

if($_POST["btn_sub"] == "")
{
  loadFile("tool.xml", "tool.xsl");
}
else
{
  updateFile("tool.xml");
}
?>

注意: 我們正在伺服器上進行轉換並將更改應用於 XML 檔案。 這是一個跨瀏覽器解決方案。 客戶端將只從伺服器收到 HTML - 這將在任何瀏覽器中工作。

ASP 檔案

在上面的 "tool.xsl" 檔案中,HTML 表單的 action 屬性的值為 "edittool.asp"。

"edittool.asp" 頁面包含兩個函式:loadFile() 函式載入和轉換 XML 檔案以供顯示,updateFile() 函式將更改應用於 XML 檔案:

<%
function loadFile(xmlfile,xslfile)
Dim xmlDoc,xslDoc
'Load XML and XSL file
set xmlDoc = Server.CreateObject("Microsoft.XMLDOM")
xmlDoc.async = false
xmlDoc.load(xmlfile)
set xslDoc = Server.CreateObject("Microsoft.XMLDOM")
xslDoc.async = false
xslDoc.load(xslfile)
'Transform file
Response.Write(xmlDoc.transformNode(xslDoc))
end function

function updateFile(xmlfile)
Dim xmlDoc,rootEl,f
Dim i
'Load XML file
set xmlDoc = Server.CreateObject("Microsoft.XMLDOM")
xmlDoc.async = false
xmlDoc.load(xmlfile)

'Set the rootEl variable equal to

 the root element
Set rootEl = xmlDoc.documentElement

'Loop through the form collection
for i = 1 To Request.Form.Count
  'Eliminate button elements in the form
  if instr(1,Request.Form.Key(i),"btn_")=0 then
    'The selectSingleNode method queries the XML file for a single node
    'that matches a query. This query requests the value element that is
    'the child of a field element that has an id attribute which matches
    'the current key value in the Form Collection. When there is a match -
    'set the text property equal to the value of the current field in the
    'Form Collection.
    set f = rootEl.selectSingleNode("field[@id='" & _
    Request.Form.Key(i) & "']/value")
    f.Text = Request.Form(i)
  end if
next

'Save the modified XML file
xmlDoc.save xmlfile

'Release all object references
set xmlDoc=nothing
set rootEl=nothing
set f=nothing

'Load the modified XML file with a style sheet that
'allows the client to see the edited information
loadFile xmlfile,server.MapPath("tool_updated.xsl")
end function

'If form is submitted, update the XML file and display result
' - if not, transform the XML file for editing
if Request.Form("btn_sub")="" then
  loadFile server.MapPath("tool.xml"),server.MapPath("tool.xsl")
else
  updateFile server.MapPath("tool.xml")
end if
%>

最後

為了方便其他裝置和平臺的小夥伴觀看往期文章:

微信公眾號搜尋:Let us Coding,關注後即可獲取最新文章推送

看完如果覺得有幫助,歡迎點贊、收藏、關注

相關文章