我需要将少数具有公共ID的节点的值相加。
我的输入XML如下:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Rowsets CachedTime="" DateCreated="2014-05-01T13:11:42" EndDate="2014-05-01T13:11:42" StartDate="2014-05-01T12:11:42" Version="14.0 SP4 Patch 0 (Nov 22, 2013)">
<Rowset>
<Columns>
<Column Description="ID" MaxRange="1" MinRange="0" Name="ID" SQLDataType="12" SourceColumn="ID"/>
<Column Description="Name" MaxRange="1" MinRange="0" Name="Name" SQLDataType="12" SourceColumn="Name"/>
<Column Description="ProductCode" MaxRange="1" MinRange="0" Name="ProductCode" SQLDataType="1" SourceColumn="ProductCode"/>
<Column Description="NoOfMachine" MaxRange="1" MinRange="0" Name="NoOfMachine" SQLDataType="1" SourceColumn="NoOfMachine"/>
<Column Description="MPerHour" MaxRange="1" MinRange="0" Name="MPerHour" SQLDataType="3" SourceColumn="MPerHour"/>
<Column Description="TargetProduction" MaxRange="1" MinRange="0" Name="TargetProduction" SQLDataType="3" SourceColumn="TargetProduction"/>
<Column Description="ActualProduction" MaxRange="1" MinRange="0" Name="ActualProduction" SQLDataType="3" SourceColumn="ActualProduction"/>
</Columns>
<Row>
<ID>S111</ID>
<Name/>
<ActualHours>25</ActualHours>
<ProductCode>16J16</ProductCode>
<NoOfMachine>5</NoOfMachine>
<MPerHour>10</MPerHour>
<TargetProduction>225.50</TargetProduction>
<ActualProduction>300.75</ActualProduction>
</Row>
<Row>
<ID>S111</ID>
<Name/>
<ActualHours>20</ActualHours>
<ProductCode>16J16</ProductCode>
<NoOfMachine>2</NoOfMachine>
<MPerHour>10</MPerHour>
<TargetProduction>24.50</TargetProduction>
<ActualProduction>1.25</ActualProduction>
</Row>
<Row>
<ID>S112</ID>
<Name/>
<ActualHours>25</ActualHours>
<ProductCode>16J26</ProductCode>
<NoOfMachine>5</NoOfMachine>
<MPerHour>10</MPerHour>
<TargetProduction>225.50</TargetProduction>
<ActualProduction>300.75</ActualProduction>
</Row>
<Row>
<ID>S111</ID>
<Name/>
<ActualHours>5</ActualHours>
<ProductCode>16J16</ProductCode>
<NoOfMachine>1</NoOfMachine>
<MPerHour>10</MPerHour>
<TargetProduction>5</TargetProduction>
<ActualProduction>300</ActualProduction>
</Row>
</Rowset>
</Rowsets>
我想总结<ActualHours>
,<NoOfMachines>
,<MPerHour>
,<TargetProduction>
和<ActualProduction>
的公共ID值。
因此输出XML将如下所示:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Rowsets CachedTime="" DateCreated="2014-05-01T13:11:42" EndDate="2014-05-01T13:11:42" StartDate="2014-05-01T12:11:42" Version="14.0 SP4 Patch 0 (Nov 22, 2013)">
<Rowset>
<Columns>
<Column Description="ID" MaxRange="1" MinRange="0" Name="ID" SQLDataType="12" SourceColumn="ID"/>
<Column Description="Name" MaxRange="1" MinRange="0" Name="Name" SQLDataType="12" SourceColumn="Name"/>
<Column Description="ProductCode" MaxRange="1" MinRange="0" Name="ProductCode" SQLDataType="1" SourceColumn="ProductCode"/>
<Column Description="NoOfMachine" MaxRange="1" MinRange="0" Name="NoOfMachine" SQLDataType="1" SourceColumn="NoOfMachine"/>
<Column Description="MPerHour" MaxRange="1" MinRange="0" Name="MPerHour" SQLDataType="3" SourceColumn="MPerHour"/>
<Column Description="TargetProduction" MaxRange="1" MinRange="0" Name="TargetProduction" SQLDataType="3" SourceColumn="TargetProduction"/>
<Column Description="ActualProduction" MaxRange="1" MinRange="0" Name="ActualProduction" SQLDataType="3" SourceColumn="ActualProduction"/>
</Columns>
<Row>
<ID>S111</ID>
<Name/>
<ActualHours>50</ActualHours>
<ProductCode>16J16</ProductCode>
<NoOfMachine>8</NoOfMachine>
<MPerHour>30</MPerHour>
<TargetProduction>255</TargetProduction>
<ActualProduction>602</ActualProduction>
</Row>
<Row>
<ID>S112</ID>
<Name/>
<ActualHours>25</ActualHours>
<ProductCode>16J26</ProductCode>
<NoOfMachine>5</NoOfMachine>
<MPerHour>10</MPerHour>
<TargetProduction>225.50</TargetProduction>
<ActualProduction>300.75</ActualProduction>
</Row>
</Rowset>
</Rowsets>
任何人都可以帮助我如何通过xslt实现这一目标。
答案 0 :(得分:2)
您可以使用键选择节点并按ID分组:
<xsl:key name="rows" match="Row" use="ID"/>
然后选择每个相似节点一次,与键相比:
<xsl:template match="Rowset">
<xsl:copy>
<xsl:apply-templates select="Row[generate-id(.) = generate-id(key('rows', ID))]"/>
</xsl:copy>
</xsl:template>
要对所有值求和,可以为要求求和的每个节点使用XPath表达式:
sum(//Row[ID='S112']/ActualHours)
并在模板中为每个不同的ID使用它。
编辑:更好的解决方案(由@IanRoberts建议)使用我们生成的密钥,并根据正在处理的当前节点的ID选择每个密钥:
sum(key('rows', ID)/ActualHours)
(以上示例适用于Row
上下文。)
这是一个完整的样式表,它使用这些转换,您可以将其作为起点:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="rows" match="Row" use="ID"/>
<xsl:template match="Rowset">
<xsl:copy>
<xsl:apply-templates select="Row[generate-id(.) = generate-id(key('rows', ID))]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Row">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="ActualHours | NoOfMachine | MPerHour | TargetProduction | ActualProduction">
<xsl:variable name="tag-name" select="name()"/>
<xsl:copy>
<xsl:value-of select="sum(key('rows', ../ID)/*[$tag-name=name()])"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Name | ID | ProductCode">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>