>我有以下输入XML:
<Fees>
<user>
<value>userA</value>
</user>
<feeList>
<userFee>
<owner>
<Id>owner1</Id>
</owner>
<Amount>
<sum>100</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner1</Id>
</owner>
<Amount>
<sum>100</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner2</Id>
</owner>
<Amount>
<sum>100</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner3</Id>
</owner>
<Amount>
<sum>100</sum>
</Amount>
</userFee>
</feeList>
<user>
<value>userB</value>
</user>
<feeList>
<userFee>
<owner>
<Id>owner1</Id>
</owner>
<Amount>
<sum>120</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner2</Id>
</owner>
<Amount>
<sum>100</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner3</Id>
</owner>
<Amount>
<sum>180</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner3</Id>
</owner>
<Amount>
<sum>100</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner4</Id>
</owner>
<Amount>
<sum>75</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner4</Id>
</owner>
<Amount>
<sum>25</sum>
</Amount>
</userFee>
</feeList>
feeList
中有 4 个userFee
元素。其中两个属于同一个所有者"owner1",它们需要合并,因为其中 1 个和 2 个属于不同的所有者。我需要以下输出:
user: userA
Total sum: 400
count: 3 (basically no. of unique owner id's for the user fee
owner and amount: owner1, 200 (Note there are 2 owner1 elements, and they need to be merged into one row with their sum)
owner and amount: owner2, 100
owner and amount: owner3, 100
到目前为止,我有以下 XSLT:
(...我仍在为组和合并它们而苦苦挣扎。
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="no" omit-xml-declaration="yes" />
<xsl:template match="/">
<xsl:for-each select="Fees">
user: <xsl:value-of select="user/value"/>
<!-- how to get count of unique userFee by owner ID -->
Count:<xsl:value-of select="count(feeList/userFee)"/>
Total Sum:<xsl:value-of select="sum(feeList/userFee/amount/sum)"/>
<xsl:for-each select="feeList/userFee">
<!-- how to group same owner into one and sum there amount -->
owner and amount: <xsl:value-of select="owner/Id"/>, <xsl:value-of select="amount/sum"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
不幸的是,仅限于 XSLT 1.0。 谢谢
我的意思是,我希望计数是 3。每个所有者计数 1。另外,我 当我有多个
<feeList>
时遇到问题.在 例子我只举了一个,但实际上可以有很多。<feeList>
是每个用户一个,我实际上有多个用户 文件。我认为问题在于<xsl:key name="overall" match="userFee" use="owner/Id" />
查看整个文件。我可以吗 让这个键只看每个<feeList>
元素?
基于对另一个答案的评论,在我看来,您需要同时使用所有者/ID 和用户/值的组合键。
如果您使用包含多个user
和相应feeList
的示例更新了问题,则更容易确定。
此外,要获取每个用户的所有者数量,您可以创建一个变量,为每个所有者输出字符串字符。字符串的长度将是所有者的数量。可能有一个更好的方法可以做到这一点,但现在还没有想到。
完整示例...
XML 输入(更新为具有多个user
和feeList
(
<Fees>
<user>
<value>userA</value>
</user>
<feeList>
<userFee>
<owner>
<Id>owner1</Id>
</owner>
<Amount>
<sum>100</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner1</Id>
</owner>
<Amount>
<sum>100</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner2</Id>
</owner>
<Amount>
<sum>100</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner3</Id>
</owner>
<Amount>
<sum>100</sum>
</Amount>
</userFee>
</feeList>
<user>
<value>userB</value>
</user>
<feeList>
<userFee>
<owner>
<Id>owner1</Id>
</owner>
<Amount>
<sum>120</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner2</Id>
</owner>
<Amount>
<sum>100</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner3</Id>
</owner>
<Amount>
<sum>180</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner3</Id>
</owner>
<Amount>
<sum>100</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner4</Id>
</owner>
<Amount>
<sum>75</sum>
</Amount>
</userFee>
<userFee>
<owner>
<Id>owner4</Id>
</owner>
<Amount>
<sum>25</sum>
</Amount>
</userFee>
</feeList>
</Fees>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:key name="user_fees" match="userFee" use="concat(../preceding-sibling::user[1]/value,'~',owner/Id)"/>
<xsl:template match="/*">
<xsl:for-each select="feeList">
<xsl:variable name="totalOwners">
<xsl:for-each select="userFee[count(.|key('user_fees',concat(../preceding-sibling::user[1]/value,'~',owner/Id))[1])=1]">
<xsl:text>#</xsl:text>
</xsl:for-each>
</xsl:variable>
<xsl:if test="position() > 1"><xsl:text>
</xsl:text></xsl:if>
<xsl:value-of select="concat('User: ',preceding-sibling::user[1]/value,'
')"/>
<xsl:value-of select="concat('Total Sum: ',sum(userFee/Amount/sum),'
')"/>
<xsl:value-of select="concat('Count: ', string-length($totalOwners), '
')"/>
<xsl:for-each
select="userFee[count(.|key('user_fees',concat(../preceding-sibling::user[1]/value,'~',owner/Id))[1])=1]">
<xsl:value-of
select="concat('	owner and amount: ',
owner/Id,
', ',
sum(key('user_fees',concat(../preceding-sibling::user[1]/value,'~',owner/Id))/Amount/sum),'
')"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出
User: userA
Total Sum: 400
Count: 3
owner and amount: owner1, 200
owner and amount: owner2, 100
owner and amount: owner3, 100
User: userB
Total Sum: 600
Count: 4
owner and amount: owner1, 120
owner and amount: owner2, 100
owner and amount: owner3, 280
owner and amount: owner4, 100
小提琴:http://xsltfiddle.liberty-development.net/nc4NzQ8
正如托马拉克所提到的,这是Muenchian Grouping的任务。在此标签下,您会发现很多如何使用它的示例。一开始使用起来可能有点棘手,因此 XSLT-2.0 为此类任务引入了更简单xsl:for-each-group
。
但是,这是应用此方法的一种解决方案:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<xsl:key name="overall" match="userFee" use="owner/Id" /> <!-- key required for Muenchian method -->
<xsl:template match="/Fees">
User: <xsl:value-of select="user/value"/>
<!-- iterate over unique owners - Muenchian method -->
<xsl:for-each select="feeList/userFee[generate-id() = generate-id(key('overall',owner/Id)[1])]">
Owner:<xsl:value-of select="owner/Id"/>
<!-- how to get count of unique userFee by owner ID -->
Count:<xsl:value-of select="count(key('overall',owner/Id))"/>
<!-- how to sum the amount of one owner -->
Total Sum:<xsl:value-of select="sum(key('overall',owner/Id)/Amount/sum)"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
Total count: <xsl:value-of select="count(feeList/userFee)" />
</xsl:template>
</xsl:stylesheet>
输出为:
User: userA
Owner:owner1
Count:2
Total Sum:200
Owner:owner2
Count:1
Total Sum:100
Owner:owner3
Count:1
Total Sum:100
Total count: 4