我正在尝试从AWS分配文件生成报告。我已经将CSV中的适当数据转换为XML,但不太清楚如何在XSLT1.0(.net)中进行键/分组
这是XML文件。
<?xml version="1.0" encoding="utf-16"?>
<AWS>
<BusinessUnit>
<Name>BBII Western</Name>
<Office>
<Name>Fairfield</Name>
<Job>
<JobNumber>OH4299</JobNumber>
<Phase> 35</Phase>
<CostCode> 74500</CostCode>
<Costs>
<Cost>
<ProductName>AWS Storage Gateway</ProductName>
<UsageQuantity>558.6793022</UsageQuantity>
<TotalCost>16.760536</TotalCost>
</Cost>
<Cost>
<ProductName>AWS Storage Gateway</ProductName>
<UsageQuantity>0.99999986</UsageQuantity>
<TotalCost>124.999981</TotalCost>
</Cost>
</Costs>
</Job>
</Office>
<Office>
<Name>Riconanda</Name>
<Job>
<JobNumber>4228</JobNumber>
<Phase> 92</Phase>
<CostCode> 92110</CostCode>
<Costs>
<Cost>
<ProductName>AWS Storage Gateway</ProductName>
<UsageQuantity>63.92940319</UsageQuantity>
<TotalCost>1.9179</TotalCost>
</Cost>
<Cost>
<ProductName>AWS Storage Gateway</ProductName>
<UsageQuantity>0.99999986</UsageQuantity>
<TotalCost>124.999981</TotalCost>
</Cost>
</Costs>
</Job>
</Office>
</BusinessUnit>
<BusinessUnit>
<Name>None</Name>
<Office>
<Name>None</Name>
<Job>
<JobNumber>None</JobNumber>
<Phase> </Phase>
<CostCode> </CostCode>
<Costs>
<Cost>
<ProductName>AWS Storage Gateway</ProductName>
<UsageQuantity>0.33271862</UsageQuantity>
<TotalCost>0.009982</TotalCost>
</Cost>
<Cost>
<ProductName>Amazon Elastic Compute Cloud</ProductName>
<UsageQuantity>1929.089098</UsageQuantity>
<TotalCost>183.26</TotalCost>
</Cost>
<Cost>
<ProductName>Amazon Elastic Compute Cloud</ProductName>
<UsageQuantity>4.99999976</UsageQuantity>
<TotalCost>0.5</TotalCost>
</Cost>
</Costs>
</Job>
</Office>
</BusinessUnit>
<BusinessUnit>
<Name>BBII Alternative Delivery</Name>
<Office>
<Name>Denver-Heery</Name>
<Job>
<JobNumber>199900</JobNumber>
<Phase> 16</Phase>
<CostCode> 74500</CostCode>
<Costs>
<Cost>
<ProductName>AWS Storage Gateway</ProductName>
<UsageQuantity>131.2051444</UsageQuantity>
<TotalCost>3.936191</TotalCost>
</Cost>
<Cost>
<ProductName>AWS Storage Gateway</ProductName>
<UsageQuantity>1.00000017</UsageQuantity>
<TotalCost>125.000019</TotalCost>
</Cost>
</Costs>
</Job>
</Office>
</BusinessUnit>
<BusinessUnit>
<Name>Transit</Name>
<Office>
<Name>Denver Estimating</Name>
<Job>
<JobNumber>RAILOH</JobNumber>
<Phase> N/A</Phase>
<CostCode> 74500</CostCode>
<Costs>
<Cost>
<ProductName>AWS Storage Gateway</ProductName>
<UsageQuantity>758.8392434</UsageQuantity>
<TotalCost>22.765391</TotalCost>
</Cost>
<Cost>
<ProductName>AWS Storage Gateway</ProductName>
<UsageQuantity>1.00000017</UsageQuantity>
<TotalCost>125.000019</TotalCost>
</Cost>
</Costs>
</Job>
</Office>
</BusinessUnit>
</AWS>
我想做的是在业务部门级别上,首先我想要每个ProductName的UsageQuantity和TotalCost的总和。
然后对每个办公室和工作都这样做。工作不会很难,也不需要分组。
我正在将其输出到HTML。
对于BusinessUnit,我尝试了几个关键配置,但似乎没有一个能像我预期的那样工作。
我尝试过(仅限业务部门级别):
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="html" indent="yes"/>
<xsl:key name="BU_Product"
match="BusinessUnit"
use="concat(Name, '#', Office/Job/Costs/Cost/ProductName)"/>
<xsl:template match="AWS">
<html>
<head>
<style>
table {
font-family: Verdana;
font-size: 9pt;
border-collapse: collapse;
table-layout: fixed
}
th {
background-color: light-blue;
font-weight: bold;
border: 1px solid black;
}
th.columnHeader {
text-align: center
}
th.rowHeader {
text-align: right;
padding-right: 4px;
}
td {
border: 1px solid black;
}
td.num {
text-align: right;
paddin-right:4px;
}
</style>
</head>
<body>
<xsl:apply-templates select="BusinessUnit"/>
</body>
</html>
</xsl:template>
<xsl:template match="BusinessUnit">
<table>
<tr>
<th class="columnHeader">
Business Unit:
</th>
<td colspan="2">
<xsl:value-of select="Name"/>
</td>
</tr>
<tr>
<th class="columnHeader">Product</th>
<th class="columnHeader">Usage Qty</th>
<th class="columnHeader">Cost</th>
</tr>
<xsl:for-each select="Office/Job/Costs/Cost[count(. | key('BU_Product',concat(Name, '#', Office/Job/Costs/Cost/ProductName))[1]) = 1]">
<tr>
<th class="rowHeader">
<xsl:value-of select="ProductName"/>
</th>
<td class="num">
<xsl:value-of select="format-number(sum(UsageQuantity),'##,##0.00')"/>
</td>
<td class="num">
<xsl:value-of select="format-number(sum(TotalCost), '##,##0.00')"/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
产生这个:
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
table {
font-family: Verdana;
font-size: 9pt;
border-collapse: collapse;
table-layout: fixed
}
th {
background-color: light-blue;
font-weight: bold;
border: 1px solid black;
}
th.columnHeader {
text-align: center
}
th.rowHeader {
text-align: right;
padding-right: 4px;
}
td {
border: 1px solid black;
}
td.num {
text-align: right;
paddin-right:4px;
}
</style>
</head>
<body>
<table>
<tr>
<th class="columnHeader">
Business Unit:
</th>
<td colspan="2">BBII Western</td>
</tr>
<tr>
<th class="columnHeader">Product</th>
<th class="columnHeader">Usage Qty</th>
<th class="columnHeader">Cost</th>
</tr>
<tr>
<th class="rowHeader">AWS Storage Gateway</th>
<td class="num">558.68</td>
<td class="num">16.76</td>
</tr>
<tr>
<th class="rowHeader">AWS Storage Gateway</th>
<td class="num">1.00</td>
<td class="num">125.00</td>
</tr>
<tr>
<th class="rowHeader">AWS Storage Gateway</th>
<td class="num">63.93</td>
<td class="num">1.92</td>
</tr>
<tr>
<th class="rowHeader">AWS Storage Gateway</th>
<td class="num">1.00</td>
<td class="num">125.00</td>
</tr>
</table>
<table>
<tr>
<th class="columnHeader">
Business Unit:
</th>
<td colspan="2">None</td>
</tr>
<tr>
<th class="columnHeader">Product</th>
<th class="columnHeader">Usage Qty</th>
<th class="columnHeader">Cost</th>
</tr>
<tr>
<th class="rowHeader">AWS Storage Gateway</th>
<td class="num">0.33</td>
<td class="num">0.01</td>
</tr>
<tr>
<th class="rowHeader">Amazon Elastic Compute Cloud</th>
<td class="num">1,929.09</td>
<td class="num">183.26</td>
</tr>
<tr>
<th class="rowHeader">Amazon Elastic Compute Cloud</th>
<td class="num">5.00</td>
<td class="num">0.50</td>
</tr>
</table>
<table>
<tr>
<th class="columnHeader">
Business Unit:
</th>
<td colspan="2">BBII Alternative Delivery</td>
</tr>
<tr>
<th class="columnHeader">Product</th>
<th class="columnHeader">Usage Qty</th>
<th class="columnHeader">Cost</th>
</tr>
<tr>
<th class="rowHeader">AWS Storage Gateway</th>
<td class="num">131.21</td>
<td class="num">3.94</td>
</tr>
<tr>
<th class="rowHeader">AWS Storage Gateway</th>
<td class="num">1.00</td>
<td class="num">125.00</td>
</tr>
</table>
<table>
<tr>
<th class="columnHeader">
Business Unit:
</th>
<td colspan="2">Transit</td>
</tr>
<tr>
<th class="columnHeader">Product</th>
<th class="columnHeader">Usage Qty</th>
<th class="columnHeader">Cost</th>
</tr>
<tr>
<th class="rowHeader">AWS Storage Gateway</th>
<td class="num">758.84</td>
<td class="num">22.77</td>
</tr>
<tr>
<th class="rowHeader">AWS Storage Gateway</th>
<td class="num">1.00</td>
<td class="num">125.00</td>
</tr>
</table>
</body>
</html>
不是我想要的。相同的产品名称应该加在一起。
如果您能将xml和xslt简化为问题部分,那么会更容易提供帮助。但无论如何,这里有一些改变的建议。
海岸中产品的关键
<xsl:key name="kProduct"
match="Cost"
use="concat(ancestor::BusinessUnit/Name, '#', ProductName)"/>
业务单元中的产品组循环
<xsl:variable name="bu" select="." />
<xsl:for-each
select="Office/Job/Costs/Cost[
count(. | key('kProduct',concat($bu/Name, '#', ProductName))[1]) = 1]">
该组内部的成本
<xsl:variable name="this_pg" select="." />
<xsl:variable name="this_pgm"
select="key('kProduct',concat($bu/Name, '#', $this_pg/ProductName))" />
然后用这个求和:
<xsl:value-of select="format-number(sum($this_pgm/UsageQuantity),'##,##0.00')"/>
会是这样的:
<xsl:template match="BusinessUnit">
<!-- .. table head -->
<xsl:variable name="bu" select="." />
<xsl:for-each
select="Office/Job/Costs/Cost[
count(. | key('kProduct',concat($bu/Name, '#', ProductName))[1]) = 1]">
<xsl:variable name="this_pg" select="." />
<xsl:variable name="this_pgm"
select="key('kProduct',concat($bu/Name, '#', $this_pg/ProductName))" />
<tr>
<th class="rowHeader">
<xsl:value-of select="ProductName"/>
</th>
<td class="num">
<xsl:value-of select="format-number(sum($this_pgm/UsageQuantity),'##,##0.00')"/>
</td>
<td class="num">
<xsl:value-of select="format-number(sum($this_pgm/TotalCost), '##,##0.00')"/>
</td>
</tr>
</xsl:for-each>
<!-- table end -->
</xsl:template>
并为Jobs 执行类似的操作