代码之家  ›  专栏  ›  技术社区  ›  Jakob

如何将模板应用于for each中的每个选定节点?

  •  7
  • Jakob  · 技术社区  · 17 年前

    内部 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: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>
    
    4 回复  |  直到 17 年前
        1
  •  14
  •   Tim C    17 年前

    我同意“ndim”的观点,您可能应该重新构造XSLT,以消除xsl:for-each循环。

    <xsl:for-each select="track">
       <li>
          <xsl:apply-templates select="." />
       </li>
    </xsl:for-each>
    

        2
  •  4
  •   ndim    17 年前

    我会重新构造一点(如果你不需要排序 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" 模板具有,因此 match=“跟踪” 模板从不匹配。

    如果你真的想使用 每人 这样,您需要在方法中更改以下两项之一:

    1. name="track" match=“跟踪” 模板,然后使用 <xsl:call-template/> 从内部 每人 (我的主意,比这更糟 Tim C
    2. 使用 蒂姆C <xsl:apply-templates select="."/> . 这样做的好处是避免了命名,并保留了对轨迹进行排序的可能性。
        3
  •  0
  •   Tomalak    17 年前

    我认为使用应用模板和模板模式是更干净的解决方案:

    <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>
    
        4
  •  0
  •   PJL    17 年前

    for each语句将上下文节点从唱片集更改为曲目。 默认情况下,apply templates调用将模板应用于上下文节点的子节点,在您的情况下,这些子节点是track元素的子节点。因此,与“轨迹”匹配的模板永远不会被命中。