首页
学习
活动
专区
圈层
工具
发布

XSLT:小计
EN

Stack Overflow用户
提问于 2012-01-03 17:14:41
回答 1查看 2.5K关注 0票数 3

源XML:

代码语言:javascript
复制
<Root>
    <Data>
        <Code>A</Code>
        <Value>10</Value>
    </Data>
    <Data>
        <Code>A</Code>
        <Value>10</Value>
    </Data>
    <Data>
        <Code>B</Code>
        <Value>10</Value>
    </Data>
    <Data>
        <Code>A</Code>
        <Value>2</Value>
    </Data>
    <Data>
        <Code>C</Code>
        <Value>10</Value>
    </Data>
    <Data>
        <Code>A</Code>
        <Value>5</Value>
    </Data>
    <Data>
        <Code>B</Code>
        <Value>4</Value>
    </Data>
    <Data>
        <Code>A</Code>
        <Value>10</Value>
    </Data>
    <Data>
        <Code>C</Code>
        <Value>10</Value>
    </Data>
    <Data>
        <Code>B</Code>
        <Value>10</Value>
    </Data>
    <Data>
        <Code>A</Code>
        <Value>10</Value>
    </Data>
    <Data>
        <Code>C</Code>
        <Value>5</Value>
    </Data>
....
</Root>

XSL-FO代码:

我的代码(XSL-FO)包含3列,其中每列包含'A‘、'B’、'C‘的内容。

代码语言:javascript
复制
<fo:table-body>
    <xfd:table-row-repeat xpath="Root/Data" font-family="Arial Narrow" font-size="10pt" padding-after="0.55cm">
        <xsl:if test="Code='A'">
        <fo:table-cell>
        <fo:block height="12pt">Value
        </fo:block>
        </fo:table-cell>
        <fo:table-cell>
        <fo:block height="12pt" border="0.1pt solid black" text-align="center">
            <xsl:value-of select="Value" /> 
        </fo:block>
        </fo:table-cell>
        <fo:table-cell>
        <fo:block height="12pt">Points</fo:block> 
        </fo:table-cell>
        </xsl:if>
    </xfd:table-row-repeat>
</fo:table-body>

每个列在表页脚中显示'B‘和'C’值的代码相同--我必须得到'A‘、'B’、'C‘的小计

代码语言:javascript
复制
<fo:table-body>
    <xfd:table-row-repeat xpath="Root/Data" font-family="Arial Narrow" font-size="10pt" padding-after="0.55cm">
        <xsl:if test="Code='A'">
        <fo:table-cell>
        <fo:block height="12pt">SubTotal
        </fo:block>
        </fo:table-cell>
        <fo:table-cell>
        <fo:block height="12pt" border="0.1pt solid black" text-align="center">
            <--Here Sum of first 15 A's. if the A's or B's or C's exceed by 15, then the table flows to 2nd Page. In that case, 1st Page table-footer shows individual subtotals of first 15 A's, 15 B's and C's. In 2nd Page, the subtotals should contain Subtotal of first 15 A's+ Succeeding A's, in the same way B's and C's --> 
        </fo:block>
        </fo:table-cell>
        <fo:table-cell>
        <fo:block height="12pt">Points</fo:block> 
        </fo:table-cell>
        </xsl:if>
    </xfd:table-row-repeat>
</fo:table-body>

这里,XSL代码只显示在一个列(对于Root/Data/ code ='A'),其他2列(‘B’& 'C')由相同的代码组成。

详细情况:

代码语言:javascript
复制
Condition 1): when Root/Data/Code = 'A' or 'B' or 'C'
   i need individual totals of 'A', 'B' and 'C' in Table-Footer individual Column.

Condition 2): inturn if individual count(Root/Data/Code) of 'A', 'B' & 'C' crosses 15.          Then Page flows to 2nd Page then Table-Footer in 2nd Page needs to contains subtotal of first 15 A's + the sum of succeeding A's in the same way for B's And C's

也就是说,如果源XML中存在20A、10B和25C。

代码语言:javascript
复制
In 1st Page, Table-Footer

SubtotalI(Value of 15 A's)=
SubtotalII(Value 10 B's)=   
SubtotalIII(Value 15 C's)=

In 2nd Page, Table-Footer

SubtotalI(15 A's+ next 5 A's)=   
SubtotalII(Value 10 B's)= <!--No Change as count of B's is less than 15 -->
SubtotalIII(15 C's + next 10 C's)=

我正在使用xsl:key来尝试这个逻辑,方法是通过代码标记进行分组,以计算'A‘、'B’和'C‘的和。由于我刚接触XSLT,我发现使用xsl:key解决这个逻辑太困难了。有人能帮忙解决这个逻辑吗?

提前谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-01-05 08:10:10

你要达到的目标有几个困难。在给定的点上计算小计实际上是最简单的。您只需要前面的轴和一个和来计算它:

代码语言:javascript
复制
sum(preceding::Value[../Code = 'A'])

要同时包含当前值,请使用如下所示的联合运算符:

代码语言:javascript
复制
sum(Value[../Code = 'A'] | preceding::Value[../Code = 'A'])

更大的困难是在每一页上显示不同的表“页脚”。页眉和页脚会自动在页面上重复,但是表跨越的所有页面的内容是相同的。我看到的唯一解决方案是自己分解表,每次添加一个不同的表页脚。

到目前为止,最简单的方法是一次只获取固定数量的数据元素,并将这些元素显示在一个单独的表中。您可以循环A、B和C类型中的一个-每个类型,给每个值一个单独的行。这样,表的行数总是相同的。您可以试验您可以包括的数字,以确定有多少适合在一页。

下面的代码返回一个具有前10个数据值的表。A、B和C值是直接放置在彼此下面的,但如果您愿意,可以将它们分别放置在左边、中间和右边。在表的底部,添加了三行,其中包含A、B和C的小计。

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <xsl:template match="/">
        <fo:root>
            <fo:layout-master-set>
                <fo:simple-page-master master-name="global">
                    <fo:region-body/>
                </fo:simple-page-master>
            </fo:layout-master-set>

            <fo:page-sequence master-reference="global">
                <fo:flow flow-name="xsl-region-body">

                    <fo:block>
                        <fo:table table-layout="fixed" width="150mm" border-style="solid">
                            <fo:table-column column-width="50mm"/>
                            <fo:table-column column-width="50mm"/>
                            <fo:table-column column-width="50mm"/>

                            <fo:table-body font-size="7pt">
                                <xsl:for-each select="/Root/Data[10 >= position()]">
                                    <fo:table-row border-style="solid">
                                        <fo:table-cell> 
                                            <fo:block height="12pt">
                                                <xsl:value-of select="Code" />
                                            </fo:block> 
                                        </fo:table-cell> 
                                        <fo:table-cell>
                                            <fo:block height="12pt" border="0.1pt solid black" text-align="center"> 
                                                <xsl:value-of select="Value" />  
                                            </fo:block> 
                                        </fo:table-cell> 
                                        <fo:table-cell> 
                                            <fo:block height="12pt">Points</fo:block>  
                                        </fo:table-cell> 
                                    </fo:table-row>

                                    <xsl:if test="position() = last()">
                                        <fo:table-row border-style="solid">
                                            <fo:table-cell> 
                                                <fo:block height="12pt">Subtotal A</fo:block> 
                                            </fo:table-cell> 
                                            <fo:table-cell>
                                                <fo:block height="12pt" border="0.1pt solid black" text-align="center"> 
                                                    <xsl:value-of select="sum(preceding::Value[../Code = 'A'] | Value[../Code = 'A'])" />  
                                                </fo:block> 
                                            </fo:table-cell> 
                                            <fo:table-cell> 
                                                <fo:block height="12pt">Points</fo:block>  
                                            </fo:table-cell> 
                                        </fo:table-row>
                                        <fo:table-row border-style="solid">
                                            <fo:table-cell> 
                                                <fo:block height="12pt">Subtotal B</fo:block> 
                                            </fo:table-cell> 
                                            <fo:table-cell>
                                                <fo:block height="12pt" border="0.1pt solid black" text-align="center"> 
                                                    <xsl:value-of select="sum(preceding::Value[../Code = 'B'] | Value[../Code = 'B'])" />  
                                                </fo:block> 
                                            </fo:table-cell> 
                                            <fo:table-cell> 
                                                <fo:block height="12pt">Points</fo:block>  
                                            </fo:table-cell> 
                                        </fo:table-row>
                                        <fo:table-row border-style="solid">
                                            <fo:table-cell> 
                                                <fo:block height="12pt">Subtotal C</fo:block> 
                                            </fo:table-cell> 
                                            <fo:table-cell>
                                                <fo:block height="12pt" border="0.1pt solid black" text-align="center"> 
                                                    <xsl:value-of select="sum(preceding::Value[../Code = 'C'] | Value[../Code = 'C'])" />  
                                                </fo:block> 
                                            </fo:table-cell> 
                                            <fo:table-cell> 
                                                <fo:block height="12pt">Points</fo:block>  
                                            </fo:table-cell> 
                                        </fo:table-row>
                                    </xsl:if>
                                </xsl:for-each>
                            </fo:table-body>
                        </fo:table>
                    </fo:block>

                </fo:flow>
            </fo:page-sequence>

        </fo:root>
    </xsl:template>

</xsl:stylesheet>

您仍然需要一些东西来确定需要多少个n个数据项表,然后执行一些递归调用来输出所有这些数据项。希望这一时刻足够让你重新开始!

PS:我注意到您正在使用xfd前缀。这看起来就像你正在与来自Ecrion的XF设计人员一起工作。我对它不太熟悉。上面的代码是一个普通的XSLT1.0解决方案。不确定它在XF设计中是否有效,请告诉我。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8715999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档