2012-02-13 67 views
2

我遇到了XSLT难题 - 您无法在一个条件语句中打开元素并在另一个条件语句中关闭它。我在Stackoverflow的其他地方看到了与此相关的显然相关的问题,但答案对于低脑瓦数的XSLT初学者来说有点令人费解。用于显示行中元素的XSLT

基本上我试图从我的XML在整个页面的列中显示项目。我现在只想做2列,但我希望有一个解决方案,其中列数不是硬编码的。

我的XML数据是这样的,大约有100个节点:

<?xml version="1.0" encoding="UTF-8"?> 
    <response> 
     <node type="category"> 
      <collection> 
       <node> 
        <articleId>1</articleId> 
        <headline>Merry Christmas says Google as it unveils animated Jingle Bells Doodle</headline> 
       </node> 
       <node> 
        <articleId>2</articleId> 
        <headline>Google activating 700,000 Android phones every day</headline> 
       </node> 
       <node> 
        <articleId>3</articleId> 
        <headline>Google attacked by music industry over 'broken pledges' on illegal downloading</headline> 
       </node> 
      </collection> 
     </node> 
    </response> 

我想翻译成这样的事情:

<div> 
     <div class="left"> 
      [ the articleId ] 
      [ the headline ] 
     </div> 
     <div class="right"> 
      [ the articleId ] 
      [ the headline ] 
     </div> 
    </div> 

与左边的第1条,第2条对我们试图XSLT的权利,其下一行的第3条左侧,等等,等等

这样

<xsl:for-each select="$collection/spi:node[(position() mod $columns) != 0]"> 
<xsl:variable name="pos" select="position()"/> 
<xsl:variable name="node" select="."/> 
<div> 
    <div class="left"> 
     <xsl:value-of select="../spi:node[$pos]/spi:articleId"/>] 
     <xsl:value-of select="../spi:node[$pos]/spi:headline"/> 
    </div> 
    <div class="right"> 
     <xsl:value-of select="../spi:node[$pos + 1]/spi:articleId"/> 
     <xsl:value-of select="../spi:node[$pos + 1]/spi:headline"/> 
    </div> 
</div> 
</xsl:for-each> 

但是,这只会导致空白的div和怪异的文章重复。任何XSLT大师都可以指引我们走向正确的方向吗?

干杯

回答

1

如果你写你的$ POS变量的值,你会发现它变为1,2,3 ...等,而不是1,3,...这是你可能期待的。这就是为什么你会得到重复,我想。

其实,没有必要寻找使用$ POS变量节点,因为你已经被定位于对每次第一个节点上,因此,所有你需要做的是什么这样

<xsl:for-each select="$collection/spi:node[(position() mod $columns) != 0]"> 
    <div> 
     <div class="left"> 
      <xsl:value-of select="articleId"/> 
      <xsl:value-of select="headline"/> 
     </div> 
     <div class="right"> 
      <xsl:value-of select="following-sibling::spi:node[1]/articleId"/> 
      <xsl:value-of select="following-sibling::spi:node[1]/headline"/> 
     </div> 
    </div> 
    </xsl:for-each> 

待办事项,它通常是用XSL最佳实践:应用模板,而不是的xsl:for-每个,所以你可以把它重新写这样的:

<xsl:template match="/"> 
    <xsl:variable name="collection" select="response/node/collection"/> 
    <xsl:apply-templates 
     select="$collection/spi:node[(position() mod $columns) != 0]" mode="group"/> 
</xsl:template> 

<xsl:template match="node" mode="group"> 
    <div> 
     <div class="left"> 
     <xsl:call-template name="spi:node"/> 
     </div> 
     <div class="right"> 
     <xsl:apply-templates select="following-sibling::spi:node[1]"/> 
     </div> 
    </div> 
</xsl:template> 

<xsl:template name="node" match="node"> 
    <xsl:value-of select="articleId"/> 
    <xsl:value-of select="headline"/> 
</xsl:template> 
+0

非常感谢Tim,很好的回答! – 2012-02-13 16:37:38