我有以下输入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>
userFee
中有4个feeList
个元素。其中两个属于同一所有者&#34; owner1&#34;这些需要合并,因为其中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。 谢谢
答案 0 :(得分:1)
正如Tomalak所说,这是Muenchian Grouping的任务。在此标记下,您将找到许多如何使用它的示例。在开始时使用起来可能有点棘手,因为XSLT-2.0为这类任务引入了更简单的<Body>
<!--Button to pull out marker co-ords-->
<p><button onclick="document.getElementById('latlnginpara').innerHTML = map.marker.getBounds()">Get map bounds</button></p>
<!--This is where the co-ords will sit for now-->
<div id="latlnginpara"></div>
<!--This plots a slot for the map-->
<div id="map" style="width:100%;height:500px;"></div>
<!--Now starts the Map fun-->
<script>
function myMap() {
var mapCanvas = document.getElementById("map");
var myCenter=new google.maps.LatLng(51.508742,-0.120850);
var mapOptions = {
center: myCenter,
zoom: 5,
zoomControl: true,
mapTypeControl: true,
scaleControl: true,
streetViewControl: true,
overviewMapControl: true,
rotateControl: true,
};
var map = new google.maps.Map(mapCanvas, mapOptions);
//1 marker bit
var marker;
function placeMarker(location) {
if ( marker ) {
marker.setPosition(location);
} else {
marker = new google.maps.Marker({
position: location,
map: map
});
}
}
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD5WIxyWvYfFU3vY27DM7mc-JClPwPLB0A&callback=myMap"></script>
</Body>
。
但是,这是应用此方法的一种解决方案:
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>
答案 1 :(得分:1)
我的意思是,我希望计数为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