简体   繁体   English

xsl-fo中的嵌套循环

[英]Nested loops in 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>

I have an xml file as seen above. 我有一个如上所述的xml文件。 In my .fo file I want a loop like this: 在我的.fo文件中,我想要这样的循环:

for every year in years, for every month in months for every projectElement in projectElements 每年的年数,每月的月数,对于projectElements中的每个projectElement

year = yearValue month = monthValue projectElement = projectElementValue year = yearValue month = monthValue projectElement = projectElementValue

This does not work: 这不起作用:

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

I get zero results. 我得到零结果。

This returns 4 loops as expected, but then I loose the month and year info: 这将按预期返回4个循环,但是随后我松开了月份和年份信息:

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

Thanks for your help 谢谢你的帮助

Your second <xsl:for-each> has a relative XPath expression that is attempting to address activityExport elements that are children of the current year (which do not exist, so they produce nothing). 你的第二个<xsl:for-each>具有正试图解决一个相对XPath表达式activityExport是当前的子元素year (这是不存在的,所以他们产生什么)。

If you correct the XPath to look relative to the context node, which is the year element, you will get the expected number of iterations. 如果您更正了XPath使其看起来相对于上下文节点(即year元素),则将获得预期的迭代次数。

Then you can solve the second issue of how to access the year and month values from inside the inner-most <xsl:for-each> . 然后,您可以解决第二个问题,即如何从最里面的<xsl:for-each>内部访问yearmonth值。 Below are two examples of how you can do that: 以下是如何执行此操作的两个示例:

1.) In order to use the nested <xsl:for-each> and be able to retain a reference to context of the context node from the outer <xsl:for-each> you can set a variable and reference the variable from inside the nested <xsl:for-each> statements: 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.) Avoid the use of variables and address the ancestor nodes from the context node of the inner-most <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.) Use a single <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>

You could also eliminate <xsl:for-each> and use <xsl:apply-templates> : 您还可以消除<xsl:for-each>并使用<xsl:apply-templates>

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

with a template defined 定义了模板

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

Each of the examples produces the following output from the sample XML: 每个示例都从示例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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM