xml XSLT:基于其他属性名称的特定属性值的总和
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15349131/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
XSLT: Sum of specific attribute value based on other attribute's name
提问by Daniel St-Jean
I have the following XML document (provided by a different party)
我有以下 XML 文档(由另一方提供)
<transactions>
<transaction TaxAType="11" TaxAValue="111" TaxBType="2" TaxBValue="222" TaxCType="3" TaxCValue="333"/>
<transaction TaxAType="11" TaxAValue="111" TaxBType="2" TaxBValue="222" TaxCType="3" TaxCValue="333"/>
</transactions>
I would like to write an XSLT document that would transform these lines and sum up the Tax*Value if the corresponding Tax*Type = '11' for example.
我想编写一个 XSLT 文档,如果相应的 Tax*Type = '11' 则转换这些行并总结 Tax*Value。
Is this something possible without using a template?
如果不使用模板,这可能吗?
name(), substring(), etc. functions in the XQuery? What are your thoughts on this?
XQuery 中的 name()、substring() 等函数?你对此有何看法?
回答by kamituel
Have a look at the following XSLT:
看看下面的 XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
Sum of TaxA where type = 11:
<xsl:value-of select="sum(transactions/transaction[@TaxAType='11']/@TaxAValue)" />
Sum of all tax where type = 11:
<xsl:value-of select="sum(transactions/transaction[@TaxAType='11']/@TaxAValue)
+ sum(transactions/transaction[@TaxBType='11']/@TaxBValue)
+ sum(transactions/transaction[@TaxCType='11']/@TaxCValue)" />
</xsl:template>
</xsl:stylesheet>
It computes sum of TaxAValue for nodes with TaxAType = 11 and sum of all Tax?Value for nodes with Tax?Type = 11.
它计算 TaxAType = 11 的节点的 TaxAValue 的总和,以及 TaxAType = 11 的节点的所有 Tax?Value 的总和。
回答by JLRishe
Here's a somewhat verbose, but general approach:
这是一个有点冗长但通用的方法:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="taxType" select="11" />
<xsl:template match="transactions">
<result>
<xsl:variable name="allValues"
select="transaction/@*[substring(local-name(), 5, 5) = 'Type']
[. = $taxType]" />
<xsl:call-template name="SumValues">
<xsl:with-param name="items" select="$allValues" />
</xsl:call-template>
</result>
</xsl:template>
<xsl:template name="SumValues">
<xsl:param name="items" />
<xsl:param name="total" select="0" />
<xsl:choose>
<xsl:when test="not($items)">
<xsl:value-of select="$total" />
</xsl:when>
<xsl:otherwise>
<xsl:variable name="currentItem" select="$items[1]" />
<xsl:variable name="currentValue">
<xsl:apply-templates select="$currentItem" mode="getMatchingValue" />
</xsl:variable>
<xsl:call-template name="SumValues">
<xsl:with-param name="items" select="$items[position() > 1]" />
<xsl:with-param name="total" select="$total + $currentValue" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@*" mode="getMatchingValue">
<xsl:variable name="typeCodeLetter" select="substring(local-name(), 4, 1)" />
<xsl:variable name="valueAttributeName"
select="concat('Tax', $typeCodeLetter, 'Value')" />
<xsl:variable name="matchingValueAttribute"
select="../@*[local-name() = $valueAttributeName]" />
<!-- Multiply by boolean to handle the case where the
attribute wasn't found-->
<xsl:value-of select="$matchingValueAttribute *
boolean($matchingValueAttribute)"/>
</xsl:template>
</xsl:stylesheet>
This should be able to handle any number of Tax*Types (as long as * is a single character) and the desired type can be passed in as a parameter.
这应该能够处理任意数量的Tax*Types(只要 * 是单个字符)并且所需的类型可以作为参数传入。
回答by titan.hi3
sum(transactions/transaction[@TaxAType='11']/@TaxAValue | @TaxBvalue | @ TaxCvalue)
总和(交易/交易[@TaxAType='11']/@TaxAValue | @TaxBvalue | @ TaxCvalue)
回答by DeadlyDan
This xml is not in a very format suitable for completing the type of processing you are asking to do. your best option is to use javascript or some other language with XML capabilities (C#, Java,etc etc) to extract the details you need.
此 xml 的格式不太适合完成您要求执行的处理类型。您最好的选择是使用 javascript 或其他具有 XML 功能的语言(C#、Java 等)来提取您需要的详细信息。
with javascript you could find any attribute with Tax*Type=11 and then get the value of the next attribute
使用 javascript,您可以找到 Tax*Type=11 的任何属性,然后获取下一个属性的值

