2012-03-06 11 views
1

にソース子どもを合計私はこれに似たXML構造のソースドキュメントがあります。XSLTマッピングおよび単一のターゲット属性

<FOO> 
    <BAR>x</BAR> 
    <BAR>y</BAR> 
    <BAR>z</BAR> 
</FOO> 

を私のターゲットXMLは、xの数値の和を表す数値を持つ属性を持っている必要があります、yおよびz。 x = 1、y = 2、z = 3

注:x、y、zは、実際にはソースドキュメントの数字ではありません。それらは文字であり、最初に表す数字にマッピングする必要があります。この場合

は、ターゲットは次のようになります。

<Target Sum=6> 
</Target> 

誰もが私は必要なものだろうXSLTの例がありますか?事前に

おかげ

答えて

0
<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes"/> 

<xsl:template match="/"> 
    <Target Sum="{sum(FOO/BAR)}" /> 
</xsl:template> 

EDIT:

これは少し冗長であり、それを行うには、よりエレガントな方法は、おそらくありますが、基本的に私が命名しましたハードコードされたマッピングが発生した後に再帰的にそれを呼び出して合計を計算するテンプレート:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
    <Target> 
     <xsl:attribute name="Sum"> 
     <xsl:call-template name="GetSum"> 
      <xsl:with-param name="CurrentNode" select="FOO/BAR[position()=1]"/> 
     </xsl:call-template> 
    </xsl:attribute> 
    </Target> 
    </xsl:template> 

    <xsl:template name="GetSum"> 
    <xsl:param name="CurrentNode"/> 
    <xsl:param name="Number" select="0"/> 

    <xsl:variable name="Recursive_Result"> 
     <xsl:variable name="MappedNumber"> 
     <xsl:choose> 
      <xsl:when test="$CurrentNode/. = 'x'">1</xsl:when> 
      <xsl:when test="$CurrentNode/. = 'y'">2</xsl:when> 
      <xsl:when test="$CurrentNode/. = 'z'">3</xsl:when> 
      <xsl:otherwise>0</xsl:otherwise> 
     </xsl:choose> 
     </xsl:variable> 

     <!-- if there is a next sibling, recursively call GetSum --> 
     <xsl:choose> 
     <xsl:when test="$CurrentNode/following-sibling::BAR[1]"> 
      <xsl:call-template name="GetSum"> 
      <xsl:with-param name="CurrentNode" select="$CurrentNode/following-sibling::BAR[1]"/> 
      <xsl:with-param name="Number"> 
       <xsl:value-of select="$MappedNumber"/> 
      </xsl:with-param> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$MappedNumber"/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:variable> 

    <!-- add the recursive_result to the number passed into the template. this will eventually build a sum --> 
    <xsl:value-of select="$Recursive_Result + $Number"/> 
    </xsl:template> 
</xsl:stylesheet> 
+0

ブラッド、クイックアンサーに感謝します。これは、X、Y、Zが実際にソースドキュメントの数字だった場合のトリックですが、実際は文字です。だから私はそれらを最初にマッピングする必要があります。それ、どうやったら出来るの?ありがとう、-J –

+0

ああ - 私はあなたが意味するものを見ます - 私のせいです、私は誤解しました。 X、Y、Zはどこですか?ソースドキュメント内にあるノードは何らかの形でありますか? –

+0

はい。それらは実行時の実際の値が何であるかに応じてのテキストノードです。それらを数値にマップして合計する必要があります。私はテンプレートを使ってそれらを数値に変換できますが、テンプレートから得られる結果をどのように集計するのか分かりません。理にかなっている? –

0

Aはるかに簡単、短く、効率的なソリューション:指名手配、正しい結果がを生産している

<FOO> 
    <BAR>x</BAR> 
    <BAR>y</BAR> 
    <BAR>z</BAR> 
</FOO> 

:この変換が提供されるXML文書に適用され

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:key name="kMap" match="@value" use="../@key"/> 

<xsl:variable name="vMaps" as="element()*"> 
    <map key="x" value="1"/> 
    <map key="y" value="2"/> 
    <map key="z" value="3"/> 
</xsl:variable> 

<xsl:template match="/*"> 
    <Target Sum="{sum(key('kMap', BAR, document('')))}"/> 
</xsl:template> 
</xsl:stylesheet> 

<Target Sum="6"/> 

説明xsl:keykey()関数とAVTの第3引数の適切な使用。

関連する問題