xsl-fo中的嵌套循环

时间:2013-09-04 23:19:30

标签: xslt xsl-fo

    <years>
        <year yearValue="2012">
            <months>
                <month monthValue="4">
                    <projectElements>
                        <projectElement projectElementValue="756" />
                    </projectElements>
                </month>
                <month monthValue="8">
                    <projectElements>
                        <projectElement projectElementValue="12345" />
                    </projectElements>
                </month>
            </months>
        </year>
        <year yearValue="2013">
            <months>
                <month monthValue="8">
                    <projectElements>
                        <projectElement projectElementValue="ffff" />
                        <projectElement projectElementValue="12345" />
                    </projectElements>
                </month>
            </months>
        </year>
    </years>

我有一个xml文件,如上所示。在我的.fo文件中,我想要一个这样的循环:

每年的年份, 几个月的每个月 对于projectElements中的每个projectElement

year = yearValue month = monthValue projectElement = projectElementValue

这不起作用:

<xsl:for-each select="activityExport/years/year">
<xsl:for-each select="activityExport/years/year/months/month">

我得到零结果。

这会按预期返回4个循环,但随后我会丢失月份和年份信息:

<xsl:for-each select="activityExport/years/year/months/month/projectElements/projectElement">

感谢您的帮助

2 个答案:

答案 0 :(得分:3)

你的第二个<xsl:for-each>有一个相对的XPath表达式,试图解决当前activityExport的子节点year元素(它们不存在,因此它们什么都不产生)。

如果更正XPath以查找相对于上下文节点(year元素),您将获得预期的迭代次数。

然后,您可以解决有关如何从最内层year内部访问month<xsl:for-each>值的第二个问题。以下是两个如何做到这一点的例子:

1.。)为了使用嵌套的<xsl:for-each>并且能够从外部<xsl:for-each>保留对上下文节点的上下文的引用,您可以设置变量并从内部引用变量嵌套的<xsl:for-each>语句:

<xsl:for-each select="years/year">
  <xsl:variable name="yearValue" select="@yearValue"/>
  <xsl:for-each select="months/month">
    <xsl:variable name="monthValue" select="@monthValue"/>
    <xsl:for-each select="projectElements/projectElement">
      <xsl:value-of select="concat('year = ', $yearValue, 
                                   ' month = ', $monthValue, 
                                   ' projectElement = ', @projectElementValue, 
                                   '&#xA;')"/>
    </xsl:for-each>
  </xsl:for-each>
</xsl:for-each>

2.避免使用变量并从最内层<xsl:for-each>的上下文节点寻址祖先节点:

<xsl:for-each select="years/year">
  <xsl:for-each select="months/month">
     <xsl:for-each select="projectElements/projectElement">
         <xsl:value-of select="concat('year = ', ancestor::year/@yearValue, 
                                      ' month = ', ancestor::month/@monthValue, 
                                      ' projectlement = ', @projectElementValue, 
                                      '&#xA;')"/>
     </xsl:for-each>
  </xsl:for-each>
</xsl:for-each>

3。)使用一个<xsl:for-each>

<xsl:for-each select="years/year/
                       months/month/
                        projectElements/projectElement">
    <xsl:value-of select="concat('year = ', ancestor::year/@yearValue, 
                                 ' month = ', ancestor::month/@monthValue, 
                                 ' projectlement = ', @projectElementValue, 
                                 '&#xA;')"/>
</xsl:for-each>

您还可以删除<xsl:for-each>并使用<xsl:apply-templates>

<xsl:apply-templates select="years/year/months/month/projectElements/projectElement"/>

定义模板

<xsl:template match="projectElement">
   <xsl:value-of select="concat('year = ', ancestor::year/@yearValue, 
                                ' month = ', ancestor::month/@monthValue, 
                                ' projectElement = ', @projectElementValue, 
                                '&#xA;')"/>
</xsl:template>

每个示例都从示例XML生成以下输出:

year = 2012 month = 4 projectElement = 756
year = 2012 month = 8 projectElement = 12345
year = 2013 month = 8 projectElement = ffff
year = 2013 month = 8 projectElement = 12345

答案 1 :(得分:1)

外部循环的上下文产生“activityExport / years / year”,因此内部循环应该相对于此路径(或月/月)。