xsl:for-each
和xsl:template
都用於在xsl樣式表中從xml中檢索節點。但他們之間的根本區別是什麼?請指導我。提前致謝。for-each和xsl中的模板之間的區別?
回答
我覺得這有一些做什麼用的理解push vs. pull風格處理的不僅僅是比較xsl:for-each
或xsl:template match="..."
。您經常會看到另一個學科的程序員使用很多xsl:if
,xsl:choose
和for-loops,當問題可以用更優雅的XSLTish方式解決時。
不過的問題:在我看來,如果你考慮使用xsl:for-each
,而不是處理數據,你需要重新考慮xsl:apply-templates
。在某些情況下,for循環適用於XSLT,但每當匹配的模板執行相同操作時,模板就是要走的路。根據我的經驗,您通常可以用xsl:apply-templates
代替大多數xsl:for-each
。
,因爲我看到使用匹配模板在for循環它的一些好處是:
- 的樣式表更容易維護和擴展,特別是如果源數據發生變化。
- 正如@chiborg所提到的,模板可以被重用,因爲它們沒有內置到特定的模板中。與XSLT 2.0中的
xsl:next-match
一起,您可以以強大的方式將模板鏈接在一起。 - 您不必模擬已經內置於所有XSLT處理器的行爲,也就是說,使用
xsl:apply-templates
並讓處理器爲您工作。 - 此外,我發現更容易理解和調試推式樣式表。如果您將樣式表信息劃分爲一小部分或幾部分,並編寫特定的匹配模式,可以很容易地看出哪個模板正在做什麼並追蹤問題的根源。
for-each
只能在模板中的一個位置使用。模板可以通過不同的apply-templates
調用重新使用。由於增加了靈活性,我大多使用模板而不是每個模板。
這其實並不重要,但你可能要考慮它的規則下拇指,我發現:
- 如果代碼依賴於上下文 位置(位置()),把它放在
<xsl:for-each>
。 - 如果代碼取決於上下文 節點(。或任何位置路徑),則將其放入一個匹配模板中 。
- 否則,請使用命名模板。
這些是完成不同的XSLT指令。
除了推拉式和拉式之外,這更像迭代與遞歸。
xsl:for-each
是一個迭代器指令,它具有無狀態聲明範例中迭代的所有優點和約束:好的處理器不應該監聽調用棧。
xsl:apply-templates
是一般的遞歸指令。一般意義上它比xsl:call-template
更強大:你將所選節點「拋出」到模式匹配機制,這是一個真正的「動態函數調用」。
無論是 '的for-each' 和 '模板' 是 用於檢索從XML節點中 在xsl。但在基本
它們之間的區別 是什麼下面是一些最重要的區別:
xsl:apply-templates
也更加豐富,比xsl:for-each
更深,甚至 只是因爲我們不知道將在 的節點上應用什麼代碼 - 在一般情況下,這個代碼將不同於 的n個不同節點ODE列表。將應用於 可寫的方式
xsl:apply template
S爲書面後由 人不知道原作者的代碼。
的FXSL library的實現在XSLT高階函數(HOF)是不可能的,如果 XSLT沒有足夠的<xsl:apply-templates>
指令。
摘要:模板和<xsl:apply-templates>
指令是XSLT如何實現和處理多態性。
參考:看到這個整個主題:http://www.stylusstudio.com/xsllist/200411/post60540.html
在「這整個線程」Dimitre什麼也沒有寫在這個SO頁面上。 – Roland 2013-05-22 09:25:06
@羅蘭,「這整個線程」在這裏被引用作爲參考,結合在一起的一些明亮的人的答案。在這個答案中沒有任何聲明說人會找到不同的東西。 – 2013-05-22 13:23:58
我大體上同意其他的答案,但我會說,以我的經驗,與xsl:for-each
寫的樣式表可以是一個更容易閱讀,理解和維護比一個嚴重依賴xsl:apply-templates
...尤其是xsl:apply-templates
具有隱式選擇(或非常通用的選擇,如select="node()"
)。
爲什麼?因爲很容易看到每個人會做什麼。使用apply-templates,你基本上必須(a)知道所有可能的XML輸入(如果你有一個模式,這將更容易,但是你仍然需要消化模式;並且很多時候你沒有模式,特別是對於在管道的一個階段發送的臨時中間XML數據;即使您有一個模式,您的開發框架(例如ESB或CMS)也可能無法讓您在管道的每個點上驗證XML。因此,如果無效數據在你身上不會立即得到通知),那麼你可以預測將選擇哪種節點(例如上下文節點的子節點); (b)查看樣式表中的每個模板以查看哪個模板與具有最高優先級(最後以文檔順序)的節點相匹配。處理順序也可以跳過所有文件或不同文件(導入或包含)。這可能使「很難」看到發生了什麼事情。
鑑於使用for-each,您確切知道將實例化哪些代碼:for-each中的代碼。由於每一個都需要一個明確的選擇表達式,所以你可能會有一個更窄的字段來猜測哪些節點可以匹配。
現在我並不否認apply-templates比for-each更強大和更靈活。這正是關鍵:更強大和更靈活的構造,也更難約束,理解和調試(並防止出現安全漏洞)。這是Rule of Least Power:「強大的語言(或在這種情況下,構造)禁止信息重用。」 (Also discussed here)
當您使用apply-templates時,每個模板都是更模塊化的,因此它本身的可重用性更強,但樣式表更復雜,模板之間的交互可預測性更低。當你使用for-each時,處理流程很容易預測和查看。
使用<xsl:apply-templates />
(或使用<xsl:for-each select="node()"/>
),當輸入XML的結構發生變化時,樣式表的行爲會發生變化,無需開發人員的審閱。這是好還是壞取決於你對樣式表的多少深思熟慮,以及XML模式開發人員和樣式表開發人員(可能是同一個人或可能屬於不同的組織)之間有多少良好的溝通。
對我來說,這是一個判斷的呼籲。如果您有面向文檔的XML(如HTML),其中許多元素類型實際上可以具有許多不同類型的子元素,並且具有任意深度的層次結構,並且對給定元素類型的處理並不經常取決於其上下文,那麼apply-templates是絕對必要的。另一方面,如果您有「面向數據」的XML,並且具有可預測的結構,那麼在不同的上下文中,通常不會有相同的元素類型表示相同的元素類型,因爲每個元素可以更直接地讀取和調試(並因此寫入正確和快速)。
for-each
的一種用法我還沒有見過提及:可以使用它將上下文節點切換到另一個文檔。我用它將數據XML轉換爲HTML輸入表單。與數據字段相匹配的模板包含for-每個選擇單個節點:XSD中描述要變換的數據字段的xs:element
。
使用XSD中的描述,一個數據字段可以轉換爲單選按鈕組,下拉框或純文本輸入。沒有for-each
我無法同時瀏覽這兩個文檔。
一般來說,我更喜歡匹配模板。我發現它對應於單個變換的概念,一次應用比每個節點更好,然後是下一個,然後是後一個,等等。但是這當然是個人偏好。
+1。設置上下文節點是「for-each」的一個重要用途 - 好點。通常,這是設置上下文節點的最簡潔明瞭的方法。然而,你*也可以使用'apply-templates'來做同樣的事情。換句話說,我不認爲你不能在不使用for-each的情況下同時瀏覽兩個文檔。請記住'apply-templates'可以使用模式並傳遞參數。 – LarsH 2016-07-14 17:39:24
- 1. R中'foreach'和'parallel'之間的區別?
- 2. 模板include和jquery.load之間的區別?
- 3. wpf中控制模板和數據模板之間的區別
- 4. 指令與模板之間的區別與沒有模板和Angular 1.2和1.1之間的區別?
- 5. 項目模板和版面模板之間的區別
- 6. 類模板和函數模板之間的區別
- 7. 編輯器模板和顯示模板之間的區別
- 8. Grails中的視圖和模板之間的區別
- 9. django模板標記中的formset和formset.forms之間的區別
- 10. .cpt模板和.pt模板之間有什麼區別?
- 11. Meteor.js中的模板助手和模板變量之間的區別
- 12. Composite C1中.master和.xml之間的模板有什麼區別?
- 13. C++:NVI和模板方法模式之間的區別?
- 14. 模板方法(分離)和策略模式之間的區別?
- 15. C# - 「foreach」和擴展方法之間的區別:ForEach
- 16. C#中IEnumerable類的foreach和for循環之間的區別
- 17. smarty中的foreach和迭代之間的區別
- 18. PHP中的「as $ key => $ value」和「as $ value」之間的區別foreach
- 19. lodash中的_.forEach和_.forOwn之間的區別
- 20. 什麼是產量和包含的模板之間的區別
- 21. C++模板的Class和Typename之間的區別
- 22. 擴展和模塊之間的區別?
- 23. MVVM - 模型和ViewModel之間的區別
- 24. 模塊和封閉之間的區別
- 25. 樣式和控制模板之間的區別
- 26. 參考,模板和NuGet包之間的區別?
- 27. 渲染:動作和渲染之間的區別:模板
- 28. AngularJS - 指令和模板之間的區別
- 29. 樣式和控件模板之間的區別
- 30. 模板元編程時結構和類之間的區別
我同意你容易看到每個模板中發生了什麼,但很難看到哪個模板將以什麼順序(使用apply-templates)被調用。 – LarsH 2010-12-16 16:08:15
@LarsH:這就是你使用Oxygens奇妙的調試...;) – 2010-12-16 19:39:42
你是對的,我這樣做:-),有時候它是一種生命保護。但是,只有掌握了XML輸入數據,調試才能起到幫助作用......並且它只能爲特定數據實例提供幫助。然而,如果你可以通過理解閱讀樣式表,那麼無論具體的輸入如何,與不能閱讀樣式表的理解相比,你都可以得出更多關於什麼可以發生和不可能發生的結論。 – LarsH 2010-12-16 19:48:49