Xml XSLT v1.0-如何对不均匀心房进行分组?
我正在尝试使用xslt对xml元素进行分组,这些属性实际上不共享任何公共值,我不确定是否应该使用,尽管我已经在代码中使用此方法对元素进行分组。我也在论坛上搜索过,但运气不好,因为大多数分组似乎发生在具有共同值的属性上 更具体地说,我试图实现的是在pdf上打印,一行用于多个记录,这些记录具有属性Ty(Att Ty=“PC”)上值为“PC”的Att元素的特定ID。所有这些都应该与我已经存在的分组一起发生 我的xml代码示例:Xml XSLT v1.0-如何对不均匀心房进行分组?,xml,xslt-1.0,grouping,muenchian-grouping,Xml,Xslt 1.0,Grouping,Muenchian Grouping,我正在尝试使用xslt对xml元素进行分组,这些属性实际上不共享任何公共值,我不确定是否应该使用,尽管我已经在代码中使用此方法对元素进行分组。我也在论坛上搜索过,但运气不好,因为大多数分组似乎发生在具有共同值的属性上 更具体地说,我试图实现的是在pdf上打印,一行用于多个记录,这些记录具有属性Ty(Att Ty=“PC”)上值为“PC”的Att元素的特定ID。所有这些都应该与我已经存在的分组一起发生 我的xml代码示例: <Document> <RecordDetail
<Document>
<RecordDetails>
<Record>
<contact id="0001" title="Mr" forename="John" surname="Smith" ST='M'/>
<AggSet>
<Att Ty="Addr" Id="43 Menelaou Street" />
<Att Ty="PC" Id="15230" />
<Att Ty="Num" Id="2580052635" />
</AggSet>
<Charge Amount="3.000" PT="P" />
</Record>
<Record>
<contact id="0001" title="Mr" forename="John" surname="Smith" ST='M'/>
<AggSet>
<Att Ty="Addr" Id="65 Dankan Street" />
<Att Ty="PC" Id="15236" />
<Att Ty="Num" Id="2580052635" />
</AggSet>
<Charge Amount="10.000" PT="P" />
</Record>
<Record>
<contact id="0002" title="Dr" forename= "Amy" surname="Jones" ST='Y'/>
<AggSet>
<Att Ty="Addr" Id="28 Karman Street" />
<Att Ty="PC" Id="15237" />
<Att Ty="Num" Id="2584552635" />
</AggSet>
<Charge Amount="-2.000" PT="P" />
</Record>
<Record>
...
</Record>
</RecordDetails>
</Document>
...
例如,对于记录2,3,我只想打印一行,因为它们的邮政编码对我来说属于同一个区域,因为Ty=“PC”意味着邮政,我试图在更大的区域基础上进行分组
我在Apache FOP上使用以下xsl:
<xsl:key name="ct" match="Record[Charge/@PT='P']" use="@ST"/>
<xsl:template match ="RecordDetails">
<xsl:for-each select="Record[generate-id(.)=generate-id(key('ct',@ST)[1])]">
<xsl:if test="@ST='M' and (./AggSet/Att[@Ty='PC']/@Id='15236' or ./AggSet/Att[@Ty='TZ']/@Id='15237' or ... ) ">
<fo:table-row>
<xsl:apply-templates select="."/>
</fo:table-row>
</xsl:if>
<xsl:for-each select="key('ct',@ST)">
<xsl:choose>
<xsl:when test="@ST='M' and (./AggSet/Att[@Ty='PC']/@Id='15236' or ./AggSet/Att[@Ty='TZ']/@Id='15237' or ... ) ">
</xsl:when>
<xsl:otherwise>
<fo:table-row>
<xsl:apply-templates select="."/>
</fo:table-row>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template match="Record">
<fo:table-cell>
<xsl:choose>
<xsl:when test="@ST='M' and (./AggSet/Att[@Ty='PC']/@Id='15236' or ./AggSet/Att[@Ty='TZ']/@Id='15237' or ... )">
<fo:block text-align="center">
<xsl:text>Greater area</xsl:text>
</fo:block>
</xsl:when>
<xsl:otherwise>
<fo:block text-align="center">
<xsl:value-of select="./AggSet/Att[@Ty='PC']/@Id" />
</fo:block>
</xsl:otherwise>
</xsl:choose>
</fo:table-cell>
<fo:table-cell>
<xsl:choose>
<xsl:when test="@ST='M' and (./AggSet/Att[@Ty='PC']/@Id='15236' or ./AggSet/Att[@Ty='TZ']/@Id='15237' or ... )">
<fo:block text-align="center">
<xsl:value-of select="sum(//Record[@ST='M' and (./AggSet/Att[@Ty='PC']/@Id='15236' or ./AggSet/Att[@Ty='TZ']/@Id='15237' or ... )]/contact/Charge/@Amount)" />
</fo:block>
</xsl:when>
<xsl:otherwise>
<fo:block text-align="center">
<xsl:value-of select="./Charge/@Amount" />
</fo:block>
</xsl:otherwise>
</xsl:choose>
</fo:table-cell>
</xsl:template>
大面积
尽管我在过去为在现有分组中实际共享公共属性值的元素实现了此逻辑,但上面的代码没有为我想要的聚合提供任何行,我想知道我的OR条件是否有问题,并且由于某种原因它会变为false
我错过什么了吗?
任何帮助都将不胜感激
谢谢
编辑:
正如Tomalak在我的例子中指出的,我正在尝试实现手动组,这意味着代码中的条件确实是硬编码的。我现在没有通用的方法来计算这些值。这种方法怎么样:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://tempuri.org/config"
exclude-result-prefixes="my"
>
<my:config>
<PC_group>
<item>15236</item>
<item>15237</item>
</PC_group>
<!-- more groups like this... -->
</my:config>
<!-- create a reference to our own config -->
<xsl:variable name="config" select="document('')/*/my:config" />
<xsl:variable name="PC_group" select="$config/PC_group" />
<xsl:template match="RecordDetails">
<grouped_RecordDetails>
<xsl:apply-templates mode="group" select="Record[Charge/@PT='P']" />
</grouped_RecordDetails>
</xsl:template>
<xsl:template match="Record" mode="group">
<xsl:variable name="myPC" select="AggSet/Att[@Ty = 'PC']/@Id" />
<!-- select all the PCs in this group -->
<xsl:variable name="groupPCs" select="$PC_group[item = $myPC]/item" />
<!-- identify all other members of this group -->
<xsl:variable name="groupMembers" select=". | ../Record[
Charge/@PT='P' and AggSet/Att[@Ty = 'PC']/@Id = $groupPCs
]" />
<!-- do the actual grouping, just like the Muenchian method... -->
<xsl:if test="generate-id() = generate-id($groupMembers[1])">
<!--
we are at the first Record in this group now
all the other group members are at $groupMembers
output whatever details you like here
-->
<xsl:copy-of select="." />
</xsl:if>
</xsl:template>
<xsl:template match="text()[normalize-space() = '']" />
</xsl:stylesheet>
15236
15237
样本输出
<grouped_RecordDetails>
<Record>
<contact id="0001" title="Mr" forename="John" surname="Smith" ST="M" />
<AggSet>
<Att Ty="Addr" Id="43 Menelaou Street" />
<Att Ty="PC" Id="15230" />
<Att Ty="Num" Id="2580052635" />
</AggSet>
<Charge Amount="3.000" PT="P" />
</Record>
<Record>
<contact id="0001" title="Mr" forename="John" surname="Smith" ST="M" />
<AggSet>
<Att Ty="Addr" Id="65 Dankan Street" />
<Att Ty="PC" Id="15236" />
<Att Ty="Num" Id="2580052635" />
</AggSet>
<Charge Amount="10.000" PT="P" />
</Record>
</grouped_RecordDetails>
编辑:当然,分组可以在一个大而混乱的XPath表达式中完成,如果您愿意:
<!-- identify all members of this group -->
<xsl:variable name="groupMembers" select="
. | ../Record[
Charge/@PT = 'P'
and AggSet/Att[@Ty = 'PC']/@Id = $PC_group[
item = current()/AggSet/Att[@Ty = 'PC']/@Id
]/item
]
" />
不过,将其拆分为多个变量会更容易理解。您能否更详细地解释不同邮政编码的分组方式?组是手动定义的还是可以计算的?这是可配置的还是硬编码的?非常准确的问题,请检查我在页面底部编辑的答案。