4

I have the following XML document (provided by a different party)

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

Is this something possible without using a template?

name(), substring(), etc. functions in the XQuery? What are your thoughts on this?

4

4 に答える 4

13

次の 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?Value の合計を計算します。

于 2013-03-11T21:49:40.697 に答える
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>

これは任意の数の s を処理できる必要がありTax*Type(* が 1 文字である限り)、目的の型をパラメーターとして渡すことができます。

于 2013-03-13T16:03:58.237 に答える
0

この xml は、実行しようとしているタイプの処理を完了するのに適した形式ではありません。最善の選択肢は、必要な詳細を抽出するために、JavaScript または XML 機能を備えた他の言語 (C#、Java など) を使用することです。

javascript を使用すると、Tax*Type=11 の属性を見つけて、次の属性の値を取得できます。

于 2013-03-11T21:51:12.923 に答える