3

XFormsフォームで単純な加重平均を計算する必要があります。XPathやXQueryを使用して、エレガントで宣言的な方法でそれを行うにはどうすればよいですか?

[編集済み]これはソースXMLドキュメントです:

<Examens>
    <Examen>
        <ExamenId>1</ExamenId>
        <Coef>1</Coef>
        <Notes>
            <Note>
                <EleveId>100</EleveId>
                <Valeur>4</Valeur>
            </Note>
            <Note>
                <EleveId>101</EleveId>
                <Valeur>4.2</Valeur>
            </Note>
            <Note>
                <EleveId>102</EleveId>
                <Valeur>3.8</Valeur>
            </Note>
        </Notes>
    </Examen>
    <Examen>
        <ExamenId>2</ExamenId>
        <Coef>2</Coef>
        <Notes>
            <Note>
                <EleveId>100</EleveId>
                <Valeur>5</Valeur>
            </Note>
            <Note>
                <EleveId>101</EleveId>
                <Valeur/>
            </Note>
            <Note>
                <EleveId>102</EleveId>
                <Valeur>3.5</Valeur>
            </Note>
        </Notes>
    </Examen>
    <Examen>
        <ExamenId>3</ExamenId>
        <Coef>3</Coef>
        <Notes>
            <Note>
                <EleveId>100</EleveId>
                <Valeur>6</Valeur>
            </Note>
            <Note>
                <EleveId>101</EleveId>
                <Valeur>5.4</Valeur>
            </Note>
            <Note>
                <EleveId>102</EleveId>
                <Valeur>2</Valeur>
            </Note>
        </Notes>
    </Examen>
</Examens>

次のスニペットは、値(= ./Valeur)と重み(= ./../../Coef)を正しく表示しています。

<xforms:repeat nodeset="$currentBranche//Note[EleveId=$currentEleveId]">
     <xforms:output ref="./Valeur"/>
     <xforms:output ref="./../../Coef"/>
</xforms:repeat>

Valeurところで、空の文字列であるノードも除外する必要があります。たとえば、XPathavg()関数を使用した次の単純な平均計算では、1つのノードのコンテンツが空の文字列である場合、エラー(「''をdoubleに変換できません」)が発生しました。これは問題です。ノードが存在し(モデルインスタンスの一部である)、ユーザーがまだ値を入力していない場合、値は空の文字列であるためです。

<xforms:output ref="round(avg($currentBranche//Note[EleveId=$currentEleveId]/Valeur)*100) div 100"/>

[編集]

正しい計算は次のとおりです。

EleveId = 100の場合:加重平均=(1 * 4 + 2 * 5 + 3 * 6)/(1 + 2 + 3)= 5.333
EleveId = 101の場合:加重平均=(1 * 4.2 + 3 * 5.4)/( 1 + 3)= 5.1
EleveId = 102の場合:加重平均=(1 * 3.8 + 2 * 3.5 + 3 * 2)/(1 + 2 + 3)= 2.8

4

1 に答える 1

4

XPath 1.0では以下を使用します

  sum($currentBranche//Note[EleveId=$currentEleveId]/Valeur[number(.)=number(.)])

 div

  count($currentBranche//Note[EleveId=$currentEleveId]/Valeur)

Xpath 2.0(XQuery)では、以下を使用します

round(avg($currentBranche//Note[EleveId=$currentEleveId]/Valeur
                                             [number(.)=number(.)])*100
      ) div 100

すべてのValeur値がとしてキャスト可能であることが保証されている場合はxs:decimal、次を使用します。

avg($currentBranche//Note[EleveId=$currentEleveId]/Valeur
                                                 [castable as xs:decimal]
                                                    /xs:decimal(.)
   )

この場合、(目立った)精度の低下はなく、後でformat-number()関数を使用して、小数点以下の必要な桁数を取得できます。


II。「加重平均」の生成

提供されたXMLドキュメントを考えると

<Examens>
    <Examen>
        <ExamenId>1</ExamenId>
        <Coef>1</Coef>
        <Notes>
            <Note>
                <EleveId>100</EleveId>
                <Valeur>4</Valeur>
            </Note>
            <Note>
                <EleveId>101</EleveId>
                <Valeur>4.2</Valeur>
            </Note>
            <Note>
                <EleveId>102</EleveId>
                <Valeur>3.8</Valeur>
            </Note>
        </Notes>
    </Examen>
    <Examen>
        <ExamenId>2</ExamenId>
        <Coef>2</Coef>
        <Notes>
            <Note>
                <EleveId>100</EleveId>
                <Valeur>5</Valeur>
            </Note>
            <Note>
                <EleveId>101</EleveId>
                <Valeur/>
            </Note>
            <Note>
                <EleveId>102</EleveId>
                <Valeur>3.5</Valeur>
            </Note>
        </Notes>
    </Examen>
    <Examen>
        <ExamenId>3</ExamenId>
        <Coef>3</Coef>
        <Notes>
            <Note>
                <EleveId>100</EleveId>
                <Valeur>6</Valeur>
            </Note>
            <Note>
                <EleveId>101</EleveId>
                <Valeur>5.4</Valeur>
            </Note>
            <Note>
                <EleveId>102</EleveId>
                <Valeur>2</Valeur>
            </Note>
        </Notes>
    </Examen>
</Examens>

このXPath2.0式は、加重平均を生成します。

   for $elevId in distinct-values(/*/*/*/*/EleveId)
    return
      round(100*
             (sum(/*/*/*/Note
                    [EleveId eq $elevId
                   and number(Valeur) eq number(Valeur)
                     ]
                      /(Valeur * ../../Coef)
                  )
            div
              sum(/*/*/*/Note
                    [EleveId eq $elevId
                   and number(Valeur) eq number(Valeur)
                    ]
                     /../../Coef
                  )
              )
           )
    div 100

そして、期待される正しい結果が生成されます:

5.33 5.1 2.8
于 2013-01-02T15:27:46.063 に答える