我目前正在尝试使用XSLT 1.0进行分组。我有类似的XML:
<table>
<row>
<PRODUCER type="VARCHAR" value="PRODUCER 1"/>
<PUBLICATION_CODE_-_NAME type="VARCHAR" value="PUBLICATION A"/>
<DOMESTIC type="DECIMAL" value="20"/>
<FOREIGN type="DECIMAL" value="4"/>
</row>
<row>
<PRODUCER type="VARCHAR" value="PRODUCER 1"/>
<PUBLICATION_CODE_-_NAME type="VARCHAR" value="PUBLICATION B"/>
<DOMESTIC type="DECIMAL" value="57"/>
<FOREIGN type="DECIMAL" value="10"/>
</row>
<row>
<PRODUCER type="VARCHAR" value="PRODUCER 2"/>
<PUBLICATION_CODE_-_NAME type="VARCHAR" value="PUBLICATION C"/>
<DOMESTIC type="DECIMAL" value="35"/>
<FOREIGN type="DECIMAL" value="20"/>
</row>
<row>
<PRODUCER type="VARCHAR" value="PRODUCER 2"/>
<PUBLICATION_CODE_-_NAME type="VARCHAR" value="PUBLICATION D"/>
<DOMESTIC type="DECIMAL" value="23"/>
<FOREIGN type="DECIMAL" value="18"/>
</row>
</table>
到目前为止,我已经能够实现我所希望的一切,除了根据生产者获得一笔国内和国外的资金。我已阅读过Muenchian分组和喜欢的内容,但我无法将其应用到我的XML中。我相信我必须创建一个基于生产者的密钥,如下所示。
<xsl:key name="producerkey" match="/table/row/" use="PRODUCER/@value"/>
正是在这一点上,我遇到了一个问题。我相信我必须生成id并使用这些id来分组我的值。
到目前为止,我能够生成与此类似的PDF。
| PRODUCER || PUBLICATION ||DOMESTIC||FOREIGN|
------------------------------------------
|PRODUCER 1||PUBLICATION A|| 20 || 4 |
| ||PUBLICATION B|| 57 || 10 |
| ||TOTALS || DTOTAL || FTOTAL|
|PRODUCER 2||PUBLICATION C|| 35 || 20 |
| ||PUBLICATION D|| 23 || 18 |
| ||TOTALS || DTOTAL || FTOTAL|
我正在尝试更换&#34; DTOTAL&#34;和&#34; FTOTAL&#34;通过DOMESTIC和FOREIGN列的总和以及相应的PRODUCER分组。
以下是我认为我工作的XSLT中最相关的部分,它们生成与上表类似的布局。
<xsl:template match="row">
<fo:table>
<fo:table-body font-size="10pt"
font-family="sans-serif"
line-height="10pt"
space-after.optimum="3pt">
<xsl:for-each select="current()">
<xsl:variable name="testnext" select="following-sibling::*[1]"/>
<xsl:choose>
<xsl:when test="$testnext">
<xsl:choose>
<xsl:when test="$testnext/PRODUCER/@value = child::PRODUCER/@value">
<fo:table-row>
<xsl:apply-templates select="PRODUCER"/>
<xsl:apply-templates select="PUBLICATION_CODE_-_NAME"/>
<xsl:apply-templates select="DOMESTIC"/>
<xsl:apply-templates select="FOREIGN"/>
</fo:table-row>
</xsl:when>
<xsl:otherwise>
<fo:table-row>
<xsl:apply-templates select="PRODUCER"/>
<xsl:apply-templates select="PUBLICATION_CODE_-_NAME"/>
<xsl:apply-templates select="DOMESTIC"/>
<xsl:apply-templates select="FOREIGN"/>
</fo:table-row>
<fo:table-row>
<fo:table-cell width="2.125in"
height="0.4in">
<fo:block>
<fo:leader/>
</fo:block>
</fo:table-cell>
<fo:table-cell width="3.25in"
height="0.4in">
<fo:block>
PRODUCER TOTAL
</fo:block>
</fo:table-cell>
<fo:table-cell width="0.95in"
height="0.4in">
<fo:block>
DTOTAL
</fo:block>
</fo:table-cell>
<fo:table-cell width="0.95in"
height="0.4in">
<fo:block>
FTOTAL
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<fo:table-row>
<xsl:apply-templates select="PRODUCER"/>
<xsl:apply-templates select="PUBLICATION_CODE_-_NAME"/>
<xsl:apply-templates select="DOMESTIC"/>
<xsl:apply-templates select="FOREIGN"/>
</fo:table-row>
<fo:table-row>
<fo:table-cell width="2.125in"
height="0.4in">
<fo:block>
<fo:leader/>
</fo:block>
</fo:table-cell>
<fo:table-cell width="3.25in"
height="0.4in">
<fo:block>
PRODUCER TOTAL
</fo:block>
</fo:table-cell>
<fo:table-cell width="0.95in"
height="0.4in">
<fo:block>
DTOTAL
</fo:block>
</fo:table-cell>
<fo:table-cell width="0.95in"
height="0.4in">
<fo:block>
FTOTAL
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</fo:table-body>
</fo:table>
</xsl:template>
<xsl:template match="PRODUCER">
<fo:table-cell width="2.125in"
height="0.2in">
<fo:block>
<xsl:variable name="test" select="parent::row/preceding-sibling::row[1]"/>
<xsl:choose>
<xsl:when test="$test">
<xsl:choose>
<xsl:when test="$test/PRODUCER/@value = @value">
<fo:leader/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@value"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@value"/>
</xsl:otherwise>
</xsl:choose>
</fo:block>
</fo:table-cell>
</xsl:template>
<xsl:template match="PUBLICATION_CODE_-_NAME">
<fo:table-cell width="3.25in"
height="0.2in">
<fo:block>
<xsl:value-of select="@value"/>
</fo:block>
</fo:table-cell>
</xsl:template>
<xsl:template match="DOMESTIC">
<fo:table-cell width="0.95in"
height="0.2in">
<fo:block>
<xsl:value-of select="@value"/>
</fo:block>
</fo:table-cell>
</xsl:template>
<xsl:template match="FOREIGN">
<fo:table-cell width="0.95in"
height="0.2in">
<fo:block>
<xsl:value-of select="@value"/>
</fo:block>
</fo:table-cell>
</xsl:template>
我所做的工作的基础是检查每一行的生产者,并使用该比较来确定何时在第一列中包含PRODUCER值以及何时创建包含列的总和和额外的空间。我确信我的代码有点乱,但我刚刚开始使用这项技术,并发现自学的学习曲线有点陡峭。此外,如果它是第一行,则包含PRODUCER,如果它是最后一行,则总计行将包括在完成报告之后。对于它的价值,生产者已按适当的顺序分组。
非常感谢任何和所有的帮助/建议/批评。
答案 0 :(得分:1)
这在XSLT 2中要容易得多,但是过去很久了:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="producerkey" match="row" use="PRODUCER/@value"/>
<xsl:template match="table">
<table>
<thead>
<tr>
<th>Producer</th>
<th>Publication</th>
<th>Domestic</th>
<th>Foreigh</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="row[
generate-id(.)
=
generate-id(key('producerkey',PRODUCER/@value))[1]
]">
<xsl:for-each select="key('producerkey',PRODUCER/@value)">
<tr>
<td>-
<xsl:if test="position()=1">
<xsl:value-of select="PRODUCER/@value"/>
</xsl:if>
</td>
<td><xsl:value-of select="PUBLICATION_CODE_-_NAME/@value"/></td>
<td><xsl:value-of select="DOMESTIC/@value"/></td>
<td><xsl:value-of select="FOREIGN/@value"/></td>
</tr>
</xsl:for-each>
<tr>
<td>-</td>
<td>Totals</td>
<td><xsl:value-of select="sum(key('producerkey',PRODUCER/@value)/DOMESTIC/@value)"/></td>
<td><xsl:value-of select="sum(key('producerkey',PRODUCER/@value)/FOREIGN/@value)"/></td>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>
产生
<table><thead>
<tr><th>Producer</th><th>Publication</th><th>Domestic</th><th>Foreigh</th></tr></thead><tbody>
<tr>
<td>-PRODUCER 1</td><td>PUBLICATION A</td><td>20</td><td>4</td></tr>
<tr><td>-</td><td>PUBLICATION B</td><td>57</td><td>10</td></tr>
<tr><td>-</td><td>Totals</td><td>77</td><td>14</td></tr>
<tr><td>-
PRODUCER 2</td><td>PUBLICATION C</td><td>35</td><td>20</td></tr>
<tr><td>-</td><td>PUBLICATION D</td><td>23</td><td>18</td></tr>
<tr><td>-</td><td>Totals</td><td>58</td><td>38</td></tr>
</tbody>
</table>