我知道我在这里遗漏了一些东西。在下面的XSLT转换中,实际结果与期望的结果不匹配。

for-each中,我想将match="track"模板应用于每个选定的track元素。如果我已正确理解XSLT,使用当前设置,每个所选<=>元素的子节点只与模板匹配,而不是<=>元素本身。

如何根据需要使<=>元素通过模板?我是否需要重新考虑我的整个方法?

注意:转换是使用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>
有帮助吗?

解决方案

我同意'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至少可以让你按照其他顺序对曲目进行排序,如果需要的话。

其他提示

我稍微重组了一下(如果你不需要排序,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>

使用match="track"遍历所有轨道元素,然后将默认规则应用于其后代。因此name="track"的内容与<xsl:call-template/>模板具有相同的上下文节点,因此Tim C模板永远不会匹配。

如果您真的想以这种方式使用<xsl:apply-templates select="."/>,则需要更改方法中的以下两项内容之一:

  1. 在<=>模板中添加<=>属性,然后在<=>(我的想法,而不是<=>)中使用<=>
  2. 使用<=>使用<=>的解决方案。这样做的好处是可以避免命名并保持对音轨进行排序的可能性。

我认为使用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>

for-each语句将上下文节点从相册更改为轨道。 默认情况下,apply-templates调用将模板应用于上下文节点的子节点,在您的情况下,这些子节点是track元素的子节点。因此,匹配“track”的模板永远不会被击中。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top