求助:使用XSLT 1.0基于跨路径描述分组发票项
基于TypeDesc分类规则对发票项分组的解决方案
嘿,我来帮你解决这个发票项分组的问题!你需要基于/catalog/TypeDesc里的分类描述,把/catalog/Invoice/InvoiceItem下的发票项归类到对应的组里对吧?不过我注意到你提供的输入XML里缺少了TypeDesc节点,所以先假设一个常见的分类规则结构(你可以根据实际情况修改),再给出具体的实现方案。
1. 补全包含分类规则的完整XML示例
先给你一个包含TypeDesc的完整输入XML,方便后续演示:
<catalog> <TypeDesc> <Type Group="小额费用" MinAmount="0" MaxAmount="10.000"/> <Type Group="大额费用" MinAmount="10.000" MaxAmount="100.000"/> </TypeDesc> <Invoice> <InvoiceItem Id="G001"> <Charge Amount="10.000"/> </InvoiceItem> <InvoiceItem Id="G002"> <Charge Amount="5.000"/> </InvoiceItem> <InvoiceItem Id="G003"> <Charge Amount="50.000"/> </InvoiceItem> <InvoiceItem Id="G004"> <Charge Amount="0.500"/> </InvoiceItem> </Invoice> </catalog>
2. 用XSLT实现自动分组
处理XML分组最常用的工具就是XSLT了,下面这个样式表会根据TypeDesc里的金额区间规则,自动把发票项分到对应的组里:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 把TypeDesc里的分组规则存成键值对,方便快速查找 --> <xsl:key name="group-rules" match="/catalog/TypeDesc/Type" use="@Group"/> <!-- 主处理模板 --> <xsl:template match="/"> <GroupedInvoiceItems> <!-- 遍历每个分组规则 --> <xsl:for-each select="/catalog/TypeDesc/Type"> <Group Name="{@Group}"> <!-- 筛选符合当前分组条件的发票项 --> <xsl:for-each select="/catalog/Invoice/InvoiceItem"> <xsl:variable name="item-amount" select="number(Charge/@Amount)"/> <!-- 判断金额是否在当前分组的区间内 --> <xsl:if test="$item-amount >= number(current()/@MinAmount) and $item-amount < number(current()/@MaxAmount)"> <xsl:copy-of select="."/> </xsl:if> </xsl:for-each> </Group> </xsl:for-each> </GroupedInvoiceItems> </xsl:template> </xsl:stylesheet>
3. 分组后的输出结果
把上面的XSLT应用到输入XML上,会得到如下的分组结果:
<GroupedInvoiceItems> <Group Name="小额费用"> <InvoiceItem Id="G002"> <Charge Amount="5.000"/> </InvoiceItem> <InvoiceItem Id="G004"> <Charge Amount="0.500"/> </InvoiceItem> </Group> <Group Name="大额费用"> <InvoiceItem Id="G001"> <Charge Amount="10.000"/> </InvoiceItem> <InvoiceItem Id="G003"> <Charge Amount="50.000"/> </InvoiceItem> </Group> </GroupedInvoiceItems>
4. 按需自定义调整
如果你的TypeDesc规则不是基于金额区间,而是基于类型ID关联(比如每个InvoiceItem有Type属性对应TypeDesc里的ID),只需要修改XSLT里的筛选逻辑就行,比如:
<!-- 假设InvoiceItem有Type属性,TypeDesc有ID属性,按ID匹配分组 --> <xsl:if test="@Type = current()/@ID"> <xsl:copy-of select="."/> </xsl:if>
你也可以根据实际需求,调整成字符串匹配、多维度筛选等其他判断条件。
内容的提问来源于stack exchange,提问作者Ahmed Almeshaal
相关产品推荐
相关产品推荐

