Xslt 1.0 聚合和求和
Xslt 1.0 aggregate and sum
我需要帮助在 XML 文件中汇总和求和。
我使用 Talend 聚合此文件,但使用的语言是 xslt 1.0.
这是我的原创XML:
<ROOT>
<Id>1000021</Id>
<Commandes>
<Commande>
<Id>12363806</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>4</Qty>
<QtyOrder>4</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>1</Qty>
<QtyOrder>1</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
</ROOT>
我要这个(数量根据CUG、intitule或EAN添加)
<ROOT>
<Id>1000021</Id>
<Commandes>
<Commande>
<Id>12363806</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>5</Qty>
<QtyOrder>5</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
</ROOT>
这是我的 xslt(映射):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<xsl:template match="/">
<ROOT>
<Id><xsl:value-of select="ROOT/Id" /></Id>
<Commandes>
<xsl:for-each select="ROOT/Commandes">
<Commande>
<xsl:for-each select="Commande">
<Id>
<xsl:value-of select="Id" />
</Id>
<CdeAteliers>
<xsl:for-each select="CdeAteliers">
<CdeAtelier>
<xsl:for-each select="CdeAtelier">
<AId><xsl:value-of select="AId" /></AId>
<Cartons>
<xsl:for-each select="Cartons">
<Carton>
<xsl:for-each select="Carton">
<Numero><xsl:value-of select="Numero" /></Numero>
<Produits>
<xsl:for-each select="Produits" >
<Produit>
<xsl:for-each select="Produit">
<CUG><xsl:value-of select="CUG" /></CUG>
<Intitule><xsl:value-of select="Intitule" /></Intitule>
<Qty><xsl:value-of select="Qty" /></Qty>
<QtyOrder><xsl:value-of select="QtyOrder" /></QtyOrder>
<EANs>
<xsl:for-each select="EANs">
<EAN><xsl:value-of select="EAN" /></EAN>
</xsl:for-each>
</EANs>
</xsl:for-each>
</Produit>
</xsl:for-each>
</Produits>
</xsl:for-each>
</Carton>
</xsl:for-each>
</Cartons>
</xsl:for-each>
</CdeAtelier>
</xsl:for-each>
</CdeAteliers>
</xsl:for-each>
</Commande>
</xsl:for-each>
</Commandes>
</ROOT>
</xsl:template>
</xsl:stylesheet>
我尝试对金额求和,但并没有增加金额。
我看到了 XSLT/Muenchian 分组方式 (https://en.wikipedia.org/wiki/XSLT/Muenchian_grouping) 但我不明白系统是如何工作的。
我迷失了这个问题
预先感谢您的帮助:)
编辑:
谢谢马丁的回答。
非常感谢!
但是如果是我的文件是这样的:
<ROOT>
<Id>1000021</Id>
<Commandes>
<Commande>
<Id>12363806</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>5</Qty>
<QtyOrder>5</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>5</Qty>
<QtyOrder>5</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
<Commandes>
<Commande>
<Id>12363807</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>5</Qty>
<QtyOrder>5</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>5</Qty>
<QtyOrder>5</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
</ROOT>
我有这个文件输出文件:
<?xml version="1.0" encoding="UTF-8"?><ROOT>
<Id>1000021</Id>
<Commandes>
<Commande>
<Id>12363806</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>20</Qty>
<QtyOrder>20</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
<Commandes>
<Commande>
<Id>12363807</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
</ROOT>
但我想要这个:
所有数量都在第一个控件中聚合。
<?xml version="1.0" encoding="UTF-8"?><ROOT>
<Id>1000021</Id>
<Commandes>
<Commande>
<Id>12363806</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>10</Qty>
<QtyOrder>10</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
<Commandes>
<Commande>
<Id>12363807</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>10</Qty>
<QtyOrder>10</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
</ROOT>
我该怎么办?
使用您文章中描述的密钥,您可以将其减少到
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="group" match="Produits/Produit" use="CUG"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Produit[generate-id() = generate-id(key('group', CUG)[1])]/Qty">
<xsl:copy>
<xsl:value-of select="sum(key('group', ../CUG)/Qty)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Produit[generate-id() = generate-id(key('group', CUG)[1])]/QtyOrder">
<xsl:copy>
<xsl:value-of select="sum(key('group', ../CUG)/QtyOrder)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Produit[not(generate-id() = generate-id(key('group', CUG)[1]))]"/>
</xsl:stylesheet>
如果您希望通过 CUG
对每个 Commande
分别分组 Produit
s,那么您必须将密钥定义为:
<xsl:key name="group" match="Produit" use="concat(ancestor::Commande/Id, '|', CUG)"/>
并相应地调整对 key()
函数的调用 - 例如:
<xsl:template match="Produit[generate-id() = generate-id(key('group', concat(ancestor::Commande/Id, '|', CUG))[1])]/Qty">
这是一个完整的样式表,它也(恕我直言)更简单一些:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="group" match="Produit" use="concat(ancestor::Commande/Id, '|', CUG)"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Produits">
<xsl:copy>
<xsl:apply-templates select="Produit[count(. | key('group', concat(ancestor::Commande/Id, '|', CUG))[1]) = 1]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Qty">
<xsl:copy>
<xsl:value-of select="sum(key('group', concat(ancestor::Commande/Id, '|', ../CUG))/Qty)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="QtyOrder">
<xsl:copy>
<xsl:value-of select="sum(key('group', concat(ancestor::Commande/Id, '|', ../CUG))/QtyOrder)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我需要帮助在 XML 文件中汇总和求和。 我使用 Talend 聚合此文件,但使用的语言是 xslt 1.0.
这是我的原创XML:
<ROOT>
<Id>1000021</Id>
<Commandes>
<Commande>
<Id>12363806</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>4</Qty>
<QtyOrder>4</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>1</Qty>
<QtyOrder>1</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
</ROOT>
我要这个(数量根据CUG、intitule或EAN添加)
<ROOT>
<Id>1000021</Id>
<Commandes>
<Commande>
<Id>12363806</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>5</Qty>
<QtyOrder>5</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
</ROOT>
这是我的 xslt(映射):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<xsl:template match="/">
<ROOT>
<Id><xsl:value-of select="ROOT/Id" /></Id>
<Commandes>
<xsl:for-each select="ROOT/Commandes">
<Commande>
<xsl:for-each select="Commande">
<Id>
<xsl:value-of select="Id" />
</Id>
<CdeAteliers>
<xsl:for-each select="CdeAteliers">
<CdeAtelier>
<xsl:for-each select="CdeAtelier">
<AId><xsl:value-of select="AId" /></AId>
<Cartons>
<xsl:for-each select="Cartons">
<Carton>
<xsl:for-each select="Carton">
<Numero><xsl:value-of select="Numero" /></Numero>
<Produits>
<xsl:for-each select="Produits" >
<Produit>
<xsl:for-each select="Produit">
<CUG><xsl:value-of select="CUG" /></CUG>
<Intitule><xsl:value-of select="Intitule" /></Intitule>
<Qty><xsl:value-of select="Qty" /></Qty>
<QtyOrder><xsl:value-of select="QtyOrder" /></QtyOrder>
<EANs>
<xsl:for-each select="EANs">
<EAN><xsl:value-of select="EAN" /></EAN>
</xsl:for-each>
</EANs>
</xsl:for-each>
</Produit>
</xsl:for-each>
</Produits>
</xsl:for-each>
</Carton>
</xsl:for-each>
</Cartons>
</xsl:for-each>
</CdeAtelier>
</xsl:for-each>
</CdeAteliers>
</xsl:for-each>
</Commande>
</xsl:for-each>
</Commandes>
</ROOT>
</xsl:template>
</xsl:stylesheet>
我尝试对金额求和,但并没有增加金额。 我看到了 XSLT/Muenchian 分组方式 (https://en.wikipedia.org/wiki/XSLT/Muenchian_grouping) 但我不明白系统是如何工作的。
我迷失了这个问题 预先感谢您的帮助:)
编辑:
谢谢马丁的回答。 非常感谢!
但是如果是我的文件是这样的:
<ROOT>
<Id>1000021</Id>
<Commandes>
<Commande>
<Id>12363806</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>5</Qty>
<QtyOrder>5</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>5</Qty>
<QtyOrder>5</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
<Commandes>
<Commande>
<Id>12363807</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>5</Qty>
<QtyOrder>5</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>5</Qty>
<QtyOrder>5</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
</ROOT>
我有这个文件输出文件:
<?xml version="1.0" encoding="UTF-8"?><ROOT>
<Id>1000021</Id>
<Commandes>
<Commande>
<Id>12363806</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>20</Qty>
<QtyOrder>20</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
<Commandes>
<Commande>
<Id>12363807</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
</ROOT>
但我想要这个: 所有数量都在第一个控件中聚合。
<?xml version="1.0" encoding="UTF-8"?><ROOT>
<Id>1000021</Id>
<Commandes>
<Commande>
<Id>12363806</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<Produit>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>10</Qty>
<QtyOrder>10</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produit>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
<Commandes>
<Commande>
<Id>12363807</Id>
<CdeAteliers>
<CdeAtelier>
<AId>2</AId>
<Cartons>
<Carton>
<Numero>0</Numero>
<Produits>
<CUG>48384</CUG>
<Intitule>MENES ALBERT Confiture extra 370 g</Intitule>
<Qty>10</Qty>
<QtyOrder>10</QtyOrder>
<EANs>
<EAN>316233</EAN>
</EANs>
</Produits>
</Carton>
</Cartons>
</CdeAtelier>
</CdeAteliers>
</Commande>
</Commandes>
</ROOT>
我该怎么办?
使用您文章中描述的密钥,您可以将其减少到
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="group" match="Produits/Produit" use="CUG"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Produit[generate-id() = generate-id(key('group', CUG)[1])]/Qty">
<xsl:copy>
<xsl:value-of select="sum(key('group', ../CUG)/Qty)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Produit[generate-id() = generate-id(key('group', CUG)[1])]/QtyOrder">
<xsl:copy>
<xsl:value-of select="sum(key('group', ../CUG)/QtyOrder)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Produit[not(generate-id() = generate-id(key('group', CUG)[1]))]"/>
</xsl:stylesheet>
如果您希望通过 CUG
对每个 Commande
分别分组 Produit
s,那么您必须将密钥定义为:
<xsl:key name="group" match="Produit" use="concat(ancestor::Commande/Id, '|', CUG)"/>
并相应地调整对 key()
函数的调用 - 例如:
<xsl:template match="Produit[generate-id() = generate-id(key('group', concat(ancestor::Commande/Id, '|', CUG))[1])]/Qty">
这是一个完整的样式表,它也(恕我直言)更简单一些:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="group" match="Produit" use="concat(ancestor::Commande/Id, '|', CUG)"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Produits">
<xsl:copy>
<xsl:apply-templates select="Produit[count(. | key('group', concat(ancestor::Commande/Id, '|', CUG))[1]) = 1]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Qty">
<xsl:copy>
<xsl:value-of select="sum(key('group', concat(ancestor::Commande/Id, '|', ../CUG))/Qty)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="QtyOrder">
<xsl:copy>
<xsl:value-of select="sum(key('group', concat(ancestor::Commande/Id, '|', ../CUG))/QtyOrder)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>