另外一个问题是,当你现在不再是你正在编写它的元素的其他子元素时,应用模板是正常的.在我的情况下,在与文档根目录匹配的模板中,我说apply-templates.然后它发现电子书是它唯一的孩子,但我可以有一个“书”元素,区分“正规”书和电子书,然后它只会列出书的字符数据.那么如果我只想在最终文件中找到电子书,那么我将需要编写apply-templates select =“ebooks”.这是一个这样的情况,这取决于你知道你的文档的好吗?
谢谢,这里是我的代码(这只是为了练习):
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>
I can’t see a clear line when to use
loops and when to use templates.
我会说,你尽可能地尽可能多地避免使用应用模板.
使用for-each通过添加嵌套级别使您的程序更加复杂,并且它也不可能重新使用for-each块中的代码.使用应用模板将(当做到正确)生成更多更灵活和模块化的XSLT.
另一方面:如果您编写的复杂程度有限,重用可用性或模式化的样式表不是一个问题,所以使用for-each可能会更快更容易地遵循(对于人类读者/维护者).所以这部分是个人偏好的问题.
在你的情况下,我会发现这个优雅:
<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>
对你的另一个问题
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是毫无意义的.
做得好的时候,XSLT有能力灵活地处理不同的输入.如果您期望在某个时候可能有孩子,则应用模板不会受到伤害.
没有选择的简单应用模板是非特定的,无论在哪个(即所有这些)以及以什么顺序(即输入文档顺序)节点将被处理.所以你最终可以结束你不想处理的处理节点,或者你之前已经处理过的节点.
由于不能为未知节点写一个合理的模板,所以我倾向于避免非特定的应用模板,并且只要在输入更改时调整样式表.