首页 文章

XSLT:基于其他属性名称的特定属性值的总和

提问于
浏览
4

我有以下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>

我想编写一个XSLT文档来转换这些行,并总结Tax * Value,例如相应的Tax * Type ='11' .

这是不是可以使用模板?

XQuery中的name(),substring()等函数?你对此有何看法?

4 回答

  • 0

    看看下面的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>
    

    它计算TaxAType = 11的节点的TaxAValue的总和以及Tax?Type = 11的节点的所有Tax?的值的总和 .

  • 1

    这是一个有点冗长但通用的方法:

    <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>
    

    这应该能够处理任意数量的 Tax*Type (只要*是单个字符),并且可以将所需类型作为参数传入 .

  • 0

    此xml的格式不适合完成您要求的处理类型 . 您最好的选择是使用javascript或其他具有XML功能的语言(C#,Java等)来提取您需要的详细信息 .

    使用javascript,您可以找到Tax * Type = 11的任何属性,然后获取下一个属性的值

  • 13

    sum(交易/交易[@ TaxAType ='11'] / @ TaxAValue | @TaxBvalue | @ TaxCvalue)

相关问题