DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> 用XSLT刪除XML示例文件中的敏感內容
用XSLT刪除XML示例文件中的敏感內容
編輯:XML詳解     

在處理 XML 文件時,您可能會遇到這種情況:文件中包含敏感數據,而您喜歡的 XML 處理工具又出現了問題,比方說一個 bug。您需要向供應商提供一個引起 bug 的示例文件。當然不能隨便發送一個 XML 文件,因為可能是示例文件中的特殊標記造成了問題。您需要有一種方法清除文件中的敏感數據,同時保持文件的特殊結構特征,以便仍然能夠說明問題。如本文所述,只要一點 XSLT 技巧就能解決。

  消除內容

  清單 1 (kill-content.xslt) 中的 XSLT 腳本可以刪除所有的文本節點和屬性值,僅留下節點結構骨架。

  清單 1 (kill-content.xslt). 清除字符數據的 XSLT 腳本

<?XML version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
 XMLns:xsl="http://www.w3.org/1999/XSL/Transform"
>
 <xsl:template match="node()">
  <xsl:copy>
   <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
 </xsl:template>
 <xsl:template match="@*">
  <xsl:attribute namespace="{namespace-uri()}" name="{name()}"/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

  從第一個模板可以看出,與很多有用的腳本一樣,這裡也使用了恆等變換。第二個模板將所有屬性復制到輸出中,但省略了屬性值。第三個模板刪除了所有文本節點。所有其他節點類型,包括元素,都由第一個模板處理,該模板將節點的基本結構復制到輸出中。清單 2 是用該腳本處理的一個示例文件。

 清單 2 (patIEnts.xml). 示例 XML 文件

<?XML version="1.0" encoding="iso-8859-1"?>
<patIEnts>
 <patIEnt id='ep' admitted="2003-06-10">
  <name>Ezra Pound</name>
  <address>
   <street>45 Usura Place</street>
   <city>Hailey</city>
   <province>ID</province>
  </address>
  <condition>ore infectus</condition>
 </patIEnt>
 <patIEnt id='tse' admitted="2003-06-20">
  <name>Thomas Eliot</name>
  <address>
   <street>3 Prufrock Lane</street>
   <city>Stamford</city>
   <province>CT</province>
  </address>
  <condition>Sartor resartus</condition>
 </patIEnt>
 <patIEnt id="co" admitted="2004-11-15">
  <name>Christopher Okigbo</name>
  <address>
   <street>7 Heaven's Gate</street>
   <city>Idoto</city>
   <province>Anambra</province>
  </address>
  <condition>caeli porta quaerit</condition>
 </patIEnt>
</patIEnts>

  如果將 清單 1 中的 XSLT 腳本應用到 清單 2 中的 XML 例子,就會得到下面的 XML(忽略了 XML 聲明)。

<patients><patIEnt id="" admitted=""><name/><address><street/><city/>...

  可以看到,結果中保留了基本的元素和屬性結構,但是沒有內容了。

  增加空格

  如果徹底刪除字符數據過於極端,希望至少保留每個節點的長度,可以使用 清單 1 的一個變體。清單 3 中的 XSLT 腳本用長度相同但僅包含空格的節點代替所有字符數據。

  清單 3 (blank-content.xslt). 將所有字符數據替換為空白內容的 XSLT 腳本

<?XML version="1.0" encoding="utf-8"?>
<xsl:transform version="1.0"
 XMLns:xsl="http://www.w3.org/1999/XSL/Transform"
 XMLns:x="http://ns.ogbuji.Net/articles"
>
 <x:wsbuffer XML:space="preserve">            </x:wsbuffer>
 <xsl:variable name="wsbuf" select="string(document('')/*/x:wsbuffer)"/>
 <xsl:template match="node()">
  <xsl:copy>
   <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
 </xsl:template>
 <xsl:template match="@*">
  <xsl:attribute namespace="{namespace-uri()}" name="{name()}">
   <xsl:value-of select="translate(., ., $wsbuf)"/>
  </xsl:attribute>
 </xsl:template>
 <xsl:template match="text()">
  <xsl:value-of select="translate(., ., $wsbuf)"/>
 </xsl:template>
</xsl:transform>

 關鍵是頂層的擴展元素 x:wsbuffer,它提供了替換操作中所使用的空白字符內容。由於格式方面的原因,我減少了空格,但是該元素可以增加更多的空格,因為原始數據中的所有字符數據節點都用同樣長度的空白替換,最大長度為 x:wsbuffer 中的字符數。xml:space 屬性用於防止 XSLT 處理程序壓縮 x:wsbuffer 中的空白。x:wsbuffer 實際上可使用任何內容,作為字符數據的常備替代文本。如果使用任何非空白字符,就不需要 XML:space 屬性了。

  通過自引用 XSLT 文檔(使用 document('') 的特殊形式),變量 wsbuf 設置為替換文本。轉換的其他部分與 清單 1 類似,只不過沒有刪除文本,而是用 wsbuf 中相同位置的字符替換每個字符。與 清單 1 一樣,最終所有的輸出內容都是空白。如果希望改變結果可以嘗試修改 x:wsbuffer 的內容。

  如果將 清單 3 中的 XSLT 腳本應用於 清單 2 中的 XML,就會得到下面的 XML。

<patients>  <patIEnt id=" " admitted="     ">   <name>     </name>...

  結束語

  本文介紹了如何修改 XML 文檔,在保留基本結構不變的同時刪除或者改變內容以免洩漏敏感信息。這種技術有一定的局限性,主要是由於 XSLT 本身的局限性造成的。特別需要指出的是,如果請求解決的問題涉及到字符數據本身的特點(比方說,處理字符實體的 bug),如此處理的示例文件就丟失了關鍵信息。記住,XSLT 還丟失了 XML 文件中的其他信息,如頂層聲明、實體引用和 CDATA 節。如果這些內容對解決問題很重要,就不能使用 XSLT 清理文件。我遇到很多情形使用這些腳本就足夠了,因此這些技術仍然值得學習。如果願意使用 EXSLT 擴展(請參閱 參考資料),還可以進一步控制字符數據。



XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved