2010-08-08 24 views
2

我被困在試圖在這些限制內工作,我正在使用XSLT 1.0 {under .net}。 我希望能夠做到以下幾點: 我是的xsl:for-each'ing通過一組類型的節點的帶有修改的XSLT副本

<node> 
    <data> unknown unstructured xml </data> 
    <owner></owner> 
    </node> 

我想能夠輸出

<node> 
    <data> unknown unstructured xml </data> 
    <!--RESULT of calling an XSL template with certain parameters --> 
    </node> 

從我的搜索到目前爲止,我想我可以做這樣的事情在here

<xsl:copy> 
     <xsl:apply-template name="findownerdetails"> 
      <xsl:with-param name="data" select="something" /> 
     </xsl:apply-template> 
    </xsl:copy> 

但這顯然是無效的。任何建議如何得到這個工作或實現類似的目標?恐怕我不能直接調用apply-templates作爲我想要的模板,這取決於我爲每個節點元素創建的數據。

任何意見理解

+0

好問題(+1)。請參閱我的答案,以獲得完全符合XSLT精神的最簡單解決方案,利用最基本的XSLT設計模式 - 使用和重寫身份規則。 – 2010-08-08 23:21:48

回答

1
<xsl:template match="node"> 
    <node> 
    <xsl:copy-of select="data"/> 
    <!-- assuming this next bit in your question example 
    is something you are happy with --> 
    <xsl:call-template name="findownerdetails"> 
     <xsl:with-param name="data" select="something" /> 
    </xsl:call-template> 
    </node> 
</xsl:template> 
+0

謝謝,我希望我能想到一段時間後會這樣做。 供參考: 如果節點元素有一些我需要複製的未知屬性會發生什麼? 也有可能做一個 GreyCloud 2010-08-08 23:00:51

+1

你可以做它回答你的問題。在更復雜的情況下,或者來自不同命名空間的「所有者」元素的可能性,與重寫身份(如Dimitre的答案中)變得更加優雅(我們可以通過Dimitre的擴展和我處理更復雜案例的答案;我的在一定的複雜度下更加簡潔,Dimitre在它之上,這也是Dimitre更通用,每個XSLT編碼人員都應該知道的原因)。 (p.s.,如果以上幫助,接受答案將是很好的)。 – 2010-08-08 23:27:24

+0

感謝額外的信息喬恩,看起來像它會做的伎倆。由於Dimitre的答案不處理傳遞參數,你的答案,我會接受你的答案 - 謝謝:) – GreyCloud 2010-08-09 10:12:24

5

這是最好的使用並覆蓋解決的問題的一個典型的例子的identity rule

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

<xsl:template match="owner"> 
    <owner-details> 
     <xsl:value-of select="."/> 
    </owner-details> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉化是在這個XML施加文檔(基於所提供的具有附加屬性和所有者詳細信息的XML文檔):

<node attr1="x" attr2="y"> 
    <data> unknown unstructured xml </data> 
    <owner> 
     <details> 
      <name>John Smith </name> 
      <profession>XSLT programmer</profession> 
     </details> 
    </owner> 
</node> 

的通緝的結果產生

<node attr1="x" attr2="y"> 
    <data> unknown unstructured xml </data> 
    <owner-details>John Smith XSLT programmer</owner-details> 
</node> 

請注意

  1. 身份模板拷貝文檔中的每個節點 「原樣」 的遞歸的時尚。

  2. 我們只覆蓋我們想要以另一種方式處理的元素的標識模板。任何模板(其匹配模式比標識模板的匹配模式更具體)都會覆蓋它--XSLT處理器將始終爲節點選擇最具體的匹配模板。

  3. 使用並重寫身份規則是最根本的,功能最強大,最普遍和最優雅的XSLT設計模式。它幾乎在所有XSLT轉換中都使用:用於刪除/重命名/修改/添加特定節點並保持所有其他節點不變。

  4. OP在評論中建議此解決方案不允許傳遞參數。這不是真的。任何模板(包括身份規則)都可以寫入參數 - 當需要時。在這種特殊情況下,它是而不是需要通過模板傳遞參數。

  5. 匹配owner模板不需要調用另一個模板 - 所有的老闆 - 具體的處理都可以在這裏完成。

+0

嗨Dimitre,感謝您的解決方案,我看到了類似的答案在另一個線程中,但恐怕它不起作用,因爲我無法通過調用傳遞任何參數。 – GreyCloud 2010-08-09 10:11:10

+0

@GreyCloud:你不明白:1.你可以通過任何模板傳遞參數。對於您的問題中的問題,這是不需要的。修改問題,以便它需要傳遞參數,我會告訴你如何。 2.在匹配'owner'的模板中,您不需要調用另一個模板並將paramrter(s)傳遞給它 - 您可以在該模板中處理'owner'元素(及其子樹) - 並且是我的答案所暗示的。 – 2010-08-09 11:32:25

+0

如何通過「」傳遞參數? – GreyCloud 2010-08-09 12:23:33