使用 XSLT 对值进行分组和求和
Use XSLT to group and sum a value
我有一个 xml 看起来像这样:
<?xml version="1.0" encoding="windows-1252" ?>
<Shipment xmlns="http://oracle.com/EbizGateway/NA/SynchASN/V2">
<containerDetails>
<ContainerID>C123</ContainerID>
<DeliveryContainer>
<ContainerType>Plastic</ContainerType>
<PackedOrder>
<OrderNumber>O1234</OrderNumber>
<PackedItem>
<controldata>
<suppliernumber>A123</suppliernumber>
<customernumner>123</customernumner>
</controldata>
<ShipmentDetails>
<ShippedQuantity>3</ShippedQuantity>
</ShipmentDetails>
</PackedItem>
<PackedItem>
<controldata>
<suppliernumber>A123</suppliernumber>
<customernumner>123</customernumner>
</controldata>
<ShipmentDetails>
<ShippedQuantity>2</ShippedQuantity>
</ShipmentDetails>
</PackedItem>
<PackedItem>
<controldata>
<suppliernumber>A234</suppliernumber>
<customernumner>234</customernumner>
</controldata>
<ShipmentDetails>
<ShippedQuantity>2</ShippedQuantity>
</ShipmentDetails>
</PackedItem>
</PackedOrder>
</DeliveryContainer>
</containerDetails>
</Shipment>
我需要根据 ContainerID、suppliernumber、customernumner、ShippedQuantity 对每个 PackedItem 进行分组。
分组后,我需要将所有重复出现的 PackedItem 的装运数量相加。例如:
ContainerID suppliernumber customernumber ShippedQuantity
C123 A123 123 3
C123 A123 123 2
C123 A234 234 2
由于前两次出现重复所以需要添加数量
这必须转换如下
ContainerID suppliernumber customernumber ShippedQuantity
C123 A123 123 5
C123 A234 234 2
添加数量后,我需要更新两次重复出现的 ShippedQuantity,如下面的 xml 所示。除了 ShippedQuantity 之外,其余值将按原样复制。
<?xml version="1.0" encoding="windows-1252" ?>
<Shipment xmlns="http://oracle.com/EbizGateway/NA/SynchASN/V2">
<containerDetails>
<ContainerID>C123</ContainerID>
<DeliveryContainer>
<ContainerType>Plastic</ContainerType>
<PackedOrder>
<OrderNumber>O1234</OrderNumber>
<PackedItem>
<controldata>
<suppliernumber>A123</suppliernumber>
<customernumner>123</customernumner>
</controldata>
<ShipmentDetails>
<ShippedQuantity>5</ShippedQuantity>
</ShipmentDetails>
</PackedItem>
<PackedItem>
<controldata>
<suppliernumber>A123</suppliernumber>
<customernumner>123</customernumner>
</controldata>
<ShipmentDetails>
<ShippedQuantity>5</ShippedQuantity>
</ShipmentDetails>
</PackedItem>
<PackedItem>
<controldata>
<suppliernumber>A234</suppliernumber>
<customernumner>234</customernumner>
</controldata>
<ShipmentDetails>
<ShippedQuantity>2</ShippedQuantity>
</ShipmentDetails>
</PackedItem>
</PackedOrder>
</DeliveryContainer>
</containerDetails>
</Shipment>
我尝试了很多选项,但无法真正理解如何在每个重复的 packedItem 中填充装运数量的总和。 :( PFB 下面的 xslt 我尝试了相同的地方..它不起作用..
<xsl:key name="ContRef" match="tns:PackedItem"
use="concat(../../../tns:ContainerID,../../tns:ContainerType,./tns:controldata/tns:suppliernumber,./tns:controldata/tns:customernumner,./tns:ShipmentDetails/tns:ShippedQuantity,' ',generate-id(./ancestor::tns:containerDetails))"/>
<xsl:template match="/">
<tns:Shipment>
<xsl:for-each select="/tns:Shipment">
<xsl:for-each select="./tns:containerDetails/tns:DeliveryContainer/tns:PackedOrder/tns:PackedItem[generate-id(.)=generate-id(key('ContRef',concat(../../../tns:ContainerID,../../tns:ContainerType,./tns:controldata/tns:suppliernumber,./tns:controldata/tns:customernumner,./tns:ShipmentDetails/tns:ShippedQuantity,' ',generate-id(./ancestor::tns:containerDetails))))]">
<xsl:variable name="ContID"
select="../../../tns:ContainerID"/>
<xsl:variable name="CustPartNumber"
select="./tns:controldata/tns:customernumner"/>
<xsl:variable name="SuppPartNumber"
select="./tns:controldata/tns:suppliernumber"/>
<xsl:variable name="ShippedQty"
select="./tns:ShipmentDetails/tns:ShippedQuantity"/>
<!-- calculate total shipped quantity-->
<xsl:variable name="TotalShippedQuantity"
select="sum(key('ContRef',concat(../../../tns:ContainerID,../../tns:ContainerType,./tns:controldata/tns:suppliernumber,./tns:controldata/tns:customernumner,./tns:ShipmentDetails/tns:ShippedQuantity,' ',generate-id(./ancestor::tns:containerDetails)))/tns:ShipmentDetails/tns:ShippedQuantity)"/>
<!-- populate the total shipped quantity in each duplicate packed item -->
<xsl:for-each select="../tns:PackedItem[./tns:controldata/tns:customernumner=$CustPartNumber and ./tns:controldata/tns:suppliernumber=$SuppPartNumber and ./tns:ShipmentDetails/tns:ShippedQuantity=$ShippedQty]/tns:ShipmentDetails/tns:ShippedQuantity">
<xsl:text>inside for</xsl:text>
<xsl:value-of select="$TotalShippedQuantity"/>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</tns:Shipment>
</xsl:template>
请指教
如果您想根据 ContainerID
、suppliernumber
和 customernumner
按每个 PackedItem
进行分组,那么键应该如下所示....
<xsl:key name="ContRef"
match="tns:PackedItem"
use="concat(../../../tns:ContainerID, '|', tns:controldata/tns:suppliernumber, '|', tns:controldata/tns:customernumner)"/>
然后,要获得组中的不同项目,您可以这样做:
<xsl:for-each
select="//tns:PackedItem
[generate-id(.) = generate-id(key('ContRef',concat(../../../tns:ContainerID, '|', tns:controldata/tns:suppliernumber, '|', tns:controldata/tns:customernumner)[1]))]">
而要得到ShippedQuantity
的总和,可以使用sum
函数对当前key
中的所有相关组求和
<xsl:value-of
select="sum(key('ContRef',concat(../../../tns:ContainerID, '|', tns:controldata/tns:suppliernumber, '|', tns:controldata/tns:customernumner))/tns:ShipmentDetails/tns:ShippedQuantity)" />
初学者试试这个 XSLT
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:tns="http://oracle.com/EbizGateway/NA/SynchASN/V2">
<xsl:output method="xml" indent="yes" />
<xsl:key name="ContRef"
match="tns:PackedItem"
use="concat(../../../tns:ContainerID, '|', tns:controldata/tns:suppliernumber, '|', tns:controldata/tns:customernumner)"/>
<xsl:template match="/">
<tns:Shipment>
<xsl:for-each select="//tns:PackedItem[generate-id(.)=generate-id(key('ContRef',concat(../../../tns:ContainerID, '|', tns:controldata/tns:suppliernumber, '|', tns:controldata/tns:customernumner)[1]))]">
<!-- populate the total shipped quantity in each duplicate packed item -->
<tns:PackedItems>
<tns:ContainerID>
<xsl:value-of select="../../../tns:ContainerID" />
</tns:ContainerID>
<tns:suppliernumber>
<xsl:value-of select="tns:controldata/tns:suppliernumber" />
</tns:suppliernumber>
<tns:customernumner>
<xsl:value-of select="tns:controldata/tns:customernumner" />
</tns:customernumner>
<tns:ShippedQuantity>
<xsl:value-of select="sum(key('ContRef',concat(../../../tns:ContainerID, '|', tns:controldata/tns:suppliernumber, '|', tns:controldata/tns:customernumner))/tns:ShipmentDetails/tns:ShippedQuantity)" />
</tns:ShippedQuantity>
</tns:PackedItems>
</xsl:for-each>
</tns:Shipment>
</xsl:template>
</xsl:transform>
我有一个 xml 看起来像这样:
<?xml version="1.0" encoding="windows-1252" ?>
<Shipment xmlns="http://oracle.com/EbizGateway/NA/SynchASN/V2">
<containerDetails>
<ContainerID>C123</ContainerID>
<DeliveryContainer>
<ContainerType>Plastic</ContainerType>
<PackedOrder>
<OrderNumber>O1234</OrderNumber>
<PackedItem>
<controldata>
<suppliernumber>A123</suppliernumber>
<customernumner>123</customernumner>
</controldata>
<ShipmentDetails>
<ShippedQuantity>3</ShippedQuantity>
</ShipmentDetails>
</PackedItem>
<PackedItem>
<controldata>
<suppliernumber>A123</suppliernumber>
<customernumner>123</customernumner>
</controldata>
<ShipmentDetails>
<ShippedQuantity>2</ShippedQuantity>
</ShipmentDetails>
</PackedItem>
<PackedItem>
<controldata>
<suppliernumber>A234</suppliernumber>
<customernumner>234</customernumner>
</controldata>
<ShipmentDetails>
<ShippedQuantity>2</ShippedQuantity>
</ShipmentDetails>
</PackedItem>
</PackedOrder>
</DeliveryContainer>
</containerDetails>
</Shipment>
我需要根据 ContainerID、suppliernumber、customernumner、ShippedQuantity 对每个 PackedItem 进行分组。
分组后,我需要将所有重复出现的 PackedItem 的装运数量相加。例如:
ContainerID suppliernumber customernumber ShippedQuantity
C123 A123 123 3
C123 A123 123 2
C123 A234 234 2
由于前两次出现重复所以需要添加数量 这必须转换如下
ContainerID suppliernumber customernumber ShippedQuantity
C123 A123 123 5
C123 A234 234 2
添加数量后,我需要更新两次重复出现的 ShippedQuantity,如下面的 xml 所示。除了 ShippedQuantity 之外,其余值将按原样复制。
<?xml version="1.0" encoding="windows-1252" ?>
<Shipment xmlns="http://oracle.com/EbizGateway/NA/SynchASN/V2">
<containerDetails>
<ContainerID>C123</ContainerID>
<DeliveryContainer>
<ContainerType>Plastic</ContainerType>
<PackedOrder>
<OrderNumber>O1234</OrderNumber>
<PackedItem>
<controldata>
<suppliernumber>A123</suppliernumber>
<customernumner>123</customernumner>
</controldata>
<ShipmentDetails>
<ShippedQuantity>5</ShippedQuantity>
</ShipmentDetails>
</PackedItem>
<PackedItem>
<controldata>
<suppliernumber>A123</suppliernumber>
<customernumner>123</customernumner>
</controldata>
<ShipmentDetails>
<ShippedQuantity>5</ShippedQuantity>
</ShipmentDetails>
</PackedItem>
<PackedItem>
<controldata>
<suppliernumber>A234</suppliernumber>
<customernumner>234</customernumner>
</controldata>
<ShipmentDetails>
<ShippedQuantity>2</ShippedQuantity>
</ShipmentDetails>
</PackedItem>
</PackedOrder>
</DeliveryContainer>
</containerDetails>
</Shipment>
我尝试了很多选项,但无法真正理解如何在每个重复的 packedItem 中填充装运数量的总和。 :( PFB 下面的 xslt 我尝试了相同的地方..它不起作用..
<xsl:key name="ContRef" match="tns:PackedItem"
use="concat(../../../tns:ContainerID,../../tns:ContainerType,./tns:controldata/tns:suppliernumber,./tns:controldata/tns:customernumner,./tns:ShipmentDetails/tns:ShippedQuantity,' ',generate-id(./ancestor::tns:containerDetails))"/>
<xsl:template match="/">
<tns:Shipment>
<xsl:for-each select="/tns:Shipment">
<xsl:for-each select="./tns:containerDetails/tns:DeliveryContainer/tns:PackedOrder/tns:PackedItem[generate-id(.)=generate-id(key('ContRef',concat(../../../tns:ContainerID,../../tns:ContainerType,./tns:controldata/tns:suppliernumber,./tns:controldata/tns:customernumner,./tns:ShipmentDetails/tns:ShippedQuantity,' ',generate-id(./ancestor::tns:containerDetails))))]">
<xsl:variable name="ContID"
select="../../../tns:ContainerID"/>
<xsl:variable name="CustPartNumber"
select="./tns:controldata/tns:customernumner"/>
<xsl:variable name="SuppPartNumber"
select="./tns:controldata/tns:suppliernumber"/>
<xsl:variable name="ShippedQty"
select="./tns:ShipmentDetails/tns:ShippedQuantity"/>
<!-- calculate total shipped quantity-->
<xsl:variable name="TotalShippedQuantity"
select="sum(key('ContRef',concat(../../../tns:ContainerID,../../tns:ContainerType,./tns:controldata/tns:suppliernumber,./tns:controldata/tns:customernumner,./tns:ShipmentDetails/tns:ShippedQuantity,' ',generate-id(./ancestor::tns:containerDetails)))/tns:ShipmentDetails/tns:ShippedQuantity)"/>
<!-- populate the total shipped quantity in each duplicate packed item -->
<xsl:for-each select="../tns:PackedItem[./tns:controldata/tns:customernumner=$CustPartNumber and ./tns:controldata/tns:suppliernumber=$SuppPartNumber and ./tns:ShipmentDetails/tns:ShippedQuantity=$ShippedQty]/tns:ShipmentDetails/tns:ShippedQuantity">
<xsl:text>inside for</xsl:text>
<xsl:value-of select="$TotalShippedQuantity"/>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</tns:Shipment>
</xsl:template>
请指教
如果您想根据 ContainerID
、suppliernumber
和 customernumner
按每个 PackedItem
进行分组,那么键应该如下所示....
<xsl:key name="ContRef"
match="tns:PackedItem"
use="concat(../../../tns:ContainerID, '|', tns:controldata/tns:suppliernumber, '|', tns:controldata/tns:customernumner)"/>
然后,要获得组中的不同项目,您可以这样做:
<xsl:for-each
select="//tns:PackedItem
[generate-id(.) = generate-id(key('ContRef',concat(../../../tns:ContainerID, '|', tns:controldata/tns:suppliernumber, '|', tns:controldata/tns:customernumner)[1]))]">
而要得到ShippedQuantity
的总和,可以使用sum
函数对当前key
<xsl:value-of
select="sum(key('ContRef',concat(../../../tns:ContainerID, '|', tns:controldata/tns:suppliernumber, '|', tns:controldata/tns:customernumner))/tns:ShipmentDetails/tns:ShippedQuantity)" />
初学者试试这个 XSLT
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:tns="http://oracle.com/EbizGateway/NA/SynchASN/V2">
<xsl:output method="xml" indent="yes" />
<xsl:key name="ContRef"
match="tns:PackedItem"
use="concat(../../../tns:ContainerID, '|', tns:controldata/tns:suppliernumber, '|', tns:controldata/tns:customernumner)"/>
<xsl:template match="/">
<tns:Shipment>
<xsl:for-each select="//tns:PackedItem[generate-id(.)=generate-id(key('ContRef',concat(../../../tns:ContainerID, '|', tns:controldata/tns:suppliernumber, '|', tns:controldata/tns:customernumner)[1]))]">
<!-- populate the total shipped quantity in each duplicate packed item -->
<tns:PackedItems>
<tns:ContainerID>
<xsl:value-of select="../../../tns:ContainerID" />
</tns:ContainerID>
<tns:suppliernumber>
<xsl:value-of select="tns:controldata/tns:suppliernumber" />
</tns:suppliernumber>
<tns:customernumner>
<xsl:value-of select="tns:controldata/tns:customernumner" />
</tns:customernumner>
<tns:ShippedQuantity>
<xsl:value-of select="sum(key('ContRef',concat(../../../tns:ContainerID, '|', tns:controldata/tns:suppliernumber, '|', tns:controldata/tns:customernumner))/tns:ShipmentDetails/tns:ShippedQuantity)" />
</tns:ShippedQuantity>
</tns:PackedItems>
</xsl:for-each>
</tns:Shipment>
</xsl:template>
</xsl:transform>