2017-10-14 137 views
0

我已經在此處看到過類似的問題,但我不確定它們是否適用於我的案例,或者我是否僅僅不理解該過程。使用XSLT替換帶有文本節點的XML標記

我有一個包含一系列規則的XML文件:

<rules> 
    <rule id="1"> 
     <block> 
      [HTML content] 
     </block> 
     <block> 
      [HTML content] 
     </block> 
     <block> 
      [HTML content] 
     </block> 
    </rule> 
    <rule id="2"> 
     <block> 
      [HTML content] 
     </block> 
     <block> 
      [HTML content] 
     </block> 
    </rule> 
    [...] 
</rules> 

現在我的代碼是一樣的東西:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml"> 
    <xsl:template match="/rules/rule"> 
     [some output to create the header and title] 
     <xsl:for-each select="block"> 
      <xsl:copy-of select="./node()" /> 
     </xsl:for-each> 
     [some output to create the footer] 
    </xsl:template> 
</xsl:stylesheet> 

需要明確的是,這是不是整個文件,但而是當用戶點擊規則以查看內容並且代碼被簡化了很多時,通過AJAX調用的部分,但是關於如何顯示各種block元素需要做一些決策,但現在這些部分對於m不是必需的這個問題只會讓閱讀代碼更加困難。

在這種特殊情況下,XSLT可能看起來並不合適,因爲我直接存儲HTML內容,但這是更大型項目的一部分,數據更多地是示意圖,這實際上是我必須訴諸的唯一部分到這個解決方案。

但是,在rule標籤內有一些表格,這些表格使用規則ID和第二個數字編號,比如1-1,1-2,...問題是,我有大約20條規則和計劃以非線性方式擴展列表。現在我想在規則1和規則2之間添加一條規則,所以我必須更正以下所有表ID。這已經發生在過去,我相信會在未來再次發生,所以我想避免這種無用的額外工作,並用<id />標記代替靜態編號,例如在Table <id />-12: [...]中,並用規則的ID替換<id /> 。我試圖修改代碼以這樣的方式

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml"> 
    <xsl:template match="/rules/rule"> 
     [some output to create the header and title] 
     <xsl:for-each select="block"> 
      <xsl:copy> 
       <xsl:apply-templates select="node()|@*" /> 
      </xsl:copy> 
     </xsl:for-each> 
     [some output to create the footer] 
    </xsl:template> 
    <xsl:template match="id"><xsl:value-of select="ancestor::rule/@id" /></xsl:template> 
</xsl:stylesheet> 

的替代工作,唯一的問題是,<block>標籤不會被刪除,如上面的代碼一樣,而所有其他標籤消失。我只有一個沒有任何HMTL標籤的文本塊。

我無法想出這個解決方案,我複製它的問題,如this one,但這是我第一次遇到<xsl:copy><xsl:apply-templates>標籤,所以我真的不知道他們是如何工作的。而且,我發現的所有例子都與之前鏈接的例子類似,需要精確的副本。我還必須在主輸出周圍添加大量額外的代碼,並且我不確定這是如何與替換進行交互的。

編輯:我也嘗試了變種

  <xsl:apply-templates select="node()|@*"> 
       <xsl:copy-of select="./node()" /> 
      </xsl:apply-templates> 

for-each週期裏面,但我得到了相同的結果:無文本標籤,但是替代工作。它看起來像apply-templates標籤刪除所有標籤,但我不知道如何使它保存它們。

回答

2

看在溶液中for-each循環中,您發現:

<xsl:for-each select="block"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*" /> 
    </xsl:copy> 
</xsl:for-each> 

在這個循環中:

  • <xsl:copy>輸出開始標籤,實際上<block>
  • <xsl:apply-templates .../> - 「執行」源標籤的內容。
  • </xsl:copy>輸出結束標籤,這次是</block>

當你不想<block>標籤,只是刪除<xsl:copy></xsl:copy>

爲防止其他標籤消失,請將標識模板添加到您的 腳本中。

的原因是,元素內置的模板:

  • 沒有「複製」開始和結束標記,
  • 它只採用模板自己的孩子,包括文本節點。

你必須重寫這個,包括身份模板

+0

謝謝,它現在有效。我不知道身份模板是什麼,我從鏈接問題中的代碼中刪除了它。 – GRB