For 循环 vs. 应用模板 [英] For loops vs. apply-templates
问题描述
我最近开始对我的一些 XML 文档使用 XSLT,但我有一些问题.我在下面添加代码.在代码中,我有一个匹配电子书元素的模板.然后我想列出所有写过这本书的作者.我使用 for each 循环来执行此操作,但我也可以对其应用模板.我看不到何时使用循环以及何时使用模板的明确界限.
I have recently started using XSLT for some of my XML documents and I have some questions. I add the code below. In the code I have a template that matches ebook elements. I then want to list all the authors that wrote the book. I do it using a for each loop, but I could also apply a template to it. I can't see a clear line when to use loops and when to use templates.
另一个问题是,当您现在编写它的元素不会有其他子元素时,只说 apply-templates 是正常的.在我的例子中,在与文档根匹配的模板中,我说应用模板.然后它找到电子书,它是它的唯一孩子,但我可以有一个书籍"元素来区分普通"书籍和电子书,然后它只会列出书籍的字符数据.如果我只想要最终文档中的电子书,我将需要编写 apply-templates select="ebooks".那么这是否取决于您对文档的了解程度?
And another question is it normal to just say apply-templates when you now that there wont be other children of the element where you are writing it. In my case in the template that matches the document root I say apply-templates. Then it finds ebooks which is the only child of it, but I could have a "books" element which distinguish between "regular" books, and electronic books then it would just list the character data of the books. I then would have needed to write apply-templates select="ebooks" if I just wanted the ebooks in my final document. So is this a case of that it depends of how well you know your document?
谢谢,这是我的代码(仅供练习):
Thank you, here is my code (This is just for practicing):
XML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="ebooks.xsl"?>
<ebooks>
<ebook>
<title>Advanced Rails Recipes: 84 New Ways to Build Stunning Rails Apps</title>
<authors>
<author><name>Mike Clark</name></author>
</authors>
<pages>464</pages>
<isbn>978-0-9787-3922-5</isbn>
<programming_language>Ruby</programming_language>
<date>
<year>2008</year>
<month>5</month>
<day>1</day>
</date>
<publisher>The Pragmatic Programmers</publisher>
</ebook>
...
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<head>
<title>Library</title>
</head>
<body>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<xsl:template match="ebooks">
<h1>Ebooks</h1>
<xsl:apply-templates>
<xsl:sort select="title"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="ebook">
<h3><xsl:value-of select="title"/></h3>
<xsl:apply-templates select="date" />
<xsl:for-each select="authors/author/name">
<b><xsl:value-of select="."/>,</b>
</xsl:for-each>
</xsl:template>
<xsl:template match="date">
<table border="1">
<tr>
<th>Day</th>
<th>Month</th>
<th>Year</th>
</tr>
<tr>
<td><xsl:value-of select="day"/></td>
<td><xsl:value-of select="month"/></td>
<td><xsl:value-of select="year"/></td>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
推荐答案
这个问题有点争论,但这是我的看法.
This question is a bit argumentative, but here is my take on it.
我看不到清晰的线条何时使用循环以及何时使用模板.
I can't see a clear line when to use loops and when to use templates.
我想说的是,您应该尽量避免使用 for-each
以支持 apply-templates
.
I'd say that you shoud strive to avoid for-each
as often as possible in favor of apply-templates
.
使用 for-each
会通过添加嵌套级别使您的程序更加复杂,并且也无法重用 for-each
块中的代码.使用 apply-templates
将(如果做得好)生成更灵活和模块化的 XSLT.
Using for-each
makes your program more complex by adding nesting levels and it's also impossibe to re-use the code inside the for-each
block. Using apply-templates
will (when done right) generate more more flexible and modular XSLT.
另一方面:如果您编写的样式表具有有限的复杂性和可重用性或模块化不是问题,则使用 for-each
可能更快更容易理解(对于人类读者/维护者).所以这在一定程度上是个人喜好的问题.
On the other hand: If you write a stylesheet with limited complexity and re-usability or modualarization are not a concern, using for-each
may be quicker and easier to follow (for a human reader/maintainer). So it's partly a question of personal preference.
在你的情况下,我会觉得这很优雅:
In your case, I would find this elegant:
<xsl:template match="ebook">
<!-- ... -->
<xsl:apply-templates select="authors/author" />
<!-- ... -->
</xsl:template>
<xsl:template match="authors/author">
<b>
<xsl:value-of select="name"/>
<xsl:if test="position() < last()">,</xsl:if>
</b>
</xsl:template>
你的另一个问题
另一个问题是,当您知道您正在编写的元素不会有其他子元素时,只说 apply-templates
是否正常.
And another question is it normal to just say
apply-templates
when you know that there won't be other children of the element where you are writing it.
当您知道此元素中永远不会有任何子元素时,编写 apply-templates
就毫无意义了.
When you know there will never be any children in this element, writing apply-templates
is pointless.
如果做得好,XSLT 能够灵活地处理不同的输入.如果您希望在某个时候可能成为孩子,那么 apply-templates
不会有什么坏处.
When done right, XSLT has the ability to flexibly deal with varying input. If you expect there could be children at some point, an apply-templates
won't hurt.
没有select
的简单apply-templates
是相当不具体的,无论是which(即:所有这些)和以什么顺序(即:输入文档顺序)节点将被处理.因此,您最终可能会处理您不想处理的节点或您之前已经处理过的节点.
A simple apply-templates
without select
is rather unspecific, both in terms of which (i.e.: all of them) and in what order (i.e.: input document order) nodes will be processed. So you could end up either processing nodes you never wanted to process or node you already have processed earlier.
由于无法为未知节点编写合理的模板,我倾向于避免使用非特定 apply-templates
并在输入更改时调整我的样式表.
Since one cannot write a sensible template for unknown nodes, I tend to avoid the unspecific apply-templates
and just adapt my stylesheet when the input changes.
这篇关于For 循环 vs. 应用模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!