0
    <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

年 = 年值 月 = 月值 项目元素 = 项目元素值

这不起作用:

<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">

谢谢你的帮助

4

2 回答 2

4

你的第二个<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
于 2013-09-05T01:07:53.277 回答
1

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

于 2013-09-05T00:18:06.860 回答