我知道我在这里遗漏了一些东西。在下面的XSLT转换中,实际结果与期望的结果不匹配。
在for-each
内,我想将match="track"
模板应用于每个选定的track
元素。如果我已正确理解XSLT,那么在当前设置中,每个选定track
元素的子节点只与模板匹配,而不是track
元素本身。
如何根据需要让track
元素通过模板?我是否需要重新考虑我的整个方法?
注意:转换是使用PHP执行的。为简洁起见,省略了XML声明。
XML文档:
<album>
<title>Grave Dancers Union</title>
<track id="shove">Somebody To Shove</track>
<track id="gold">Black Gold</track>
<track id="train">Runaway Train</track>
<producer>Michael Beinhorn</producer>
</album>
XSL样式表:
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/album">
<ol>
<xsl:for-each select="track">
<li><xsl:apply-templates/></li>
</xsl:for-each>
</ol>
</xsl:template>
<xsl:template match="track">
<a href="{@id}"><xsl:apply-templates/></a>
</xsl:template>
</xsl:stylesheet>
结果:
<ol>
<li>Somebody To Shove</li>
<li>Black Gold</li>
<li>Runaway Train</li>
</ol>
期望的结果:
<ol>
<li><a href="shove">Somebody To Shove</a></li>
<li><a href="gold">Black Gold</a></li>
<li><a href="train">Runaway Train</a></li>
</ol>
答案 0 :(得分:13)
我同意'ndim'你应该重构你的XSLT以取消xsl:for-each循环。
或者,您可以修改xsl:apply-templates以选择xsl中的当前轨道节点:for-each
<xsl:for-each select="track">
<li>
<xsl:apply-templates select="." />
</li>
</xsl:for-each>
保留xsl:for-each至少可以让你按照其他顺序对曲目进行排序,如果需要的话。
答案 1 :(得分:4)
我稍微重组了一下(如果你不需要排序,for-each
方法就可以了):
<xsl:template match="/album">
<ol>
<xsl:apply-templates select="track"/>
</ol>
</xsl:template>
<xsl:template match="track">
<li><a href="{@id}"><xsl:apply-templates/></a></li>
<xsl:template>
这看起来更短,更重要,恕我直言。
我想你的
<xsl:for-each select="track">
<li><xsl:apply-templates/></li>
</xsl:for-each>
使用for-each
遍历所有跟踪元素,然后将默认规则应用于其后代。因此for-each
的内容与match="track"
模板具有相同的上下文节点,因此match="track"
模板永远不匹配。
如果您真的想以这种方式使用for-each
,则需要在方法中更改以下两项内容之一:
name="track"
模板中添加match="track"
属性,然后在<xsl:call-template/>
中使用for-each
(我的想法,而不是Tim C
)Tim C
使用<xsl:apply-templates select="."/>
的解决方案。这样做的好处是可以避免命名并保持对音轨进行排序的可能性。答案 2 :(得分:0)
我认为使用apply-templates和模板模式是更清洁的解决方案:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template match="/">
<body>
<xsl:apply-templates select="album" mode="ol" />
</body>
</xsl:template>
<xsl:template match="album" mode="ol">
<ol>
<xsl:apply-templates select="track" mode="li" />
</ol>
</xsl:template>
<xsl:template match="track" mode="li">
<li>
<xsl:apply-templates select="." />
</li>
</xsl:template>
<xsl:template match="track">
<a href="{@id}">
<xsl:value-of select="." />
</a>
</xsl:template>
</xsl:stylesheet>
结果:
<body>
<ol>
<li>
<a href="shove">Somebody To Shove</a>
</li>
<li>
<a href="gold">Black Gold</a>
</li>
<li>
<a href="train">Runaway Train</a>
</li>
</ol>
</body>
答案 3 :(得分:0)
for-each语句将上下文节点从相册更改为轨道。 默认情况下,apply-templates调用将模板应用于上下文节点的子节点,在您的情况下,这些子节点是track元素的子节点。因此,匹配“track”的模板永远不会被击中。