2017-02-23 2 views
0

私は何か変わったことに気づいた。これは私のXMLXPath - Java XPathの結果が予期しない

<Items> 
    <Item> 
     <Name>A</Name> 
     <Amount>0.0012</Amount> 
     <Quantity>17</Quantity> 
     <TotalAmount>0.0204</TotalAmount> 
    </Item> 
    <Item> 
     <Name>B</Name> 
     <Amount>1</Amount> 
     <Quantity>2</Quantity> 
     <TotalAmount>2</TotalAmount> 
    </Item> 
    <Item> 
     <Name>C</Name> 
     <Amount>3</Amount> 
     <Quantity>2</Quantity> 
     <TotalAmount>6</TotalAmount> 
    </Item> 
</Items> 

であり、これは私が

/アイテム/商品[((金額*数量)!= TotalAmount)] /名前

これを使用するXPathですXPathは、TotalAmount!= Product(金額、数量)の商品名を印刷する必要がありました。

私は値Aを取得しかし、なぜこれが起こっているので、0.0012 * 17 = 0.0204

私は理解していないと私はアイテムの「A」を削除した場合、その後、私は結果を得ることはありません。

同じことが$ /アイテム内のx /商品のためだけでなく

のXPathの新しいバージョンのために行く[((金額*数量)!= TotalAmount)]を返す $ X /名前

私はJavaでSaxon 9を使用しています。

なぜこれが起こっているのか説明できますか?

答えて

1

精度を向上させるために、xs:decimal/xs:integerを試してみてください。/Items/Item[((xs:decimal(Amount) * xs:integer(Quantity)) != TotalAmount)]/Name

<results> 
    <names-precise/> 
    <names-imprecise>A</names-imprecise> 
    <Items> 
     <Item> 
     <Name>A</Name> 
     <Amount>0.0012</Amount> 
     <Quantity>17</Quantity> 
     <TotalAmount>0.0204</TotalAmount> 
     <double-computation>0.020399999999999998</double-computation> 
     <decimal-computation>0.0204</decimal-computation> 
     </Item> 
     <Item> 
     <Name>B</Name> 
     <Amount>1</Amount> 
     <Quantity>2</Quantity> 
     <TotalAmount>2</TotalAmount> 
     <double-computation>2</double-computation> 
     <decimal-computation>2</decimal-computation> 
     </Item> 
     <Item> 
     <Name>C</Name> 
     <Amount>3</Amount> 
     <Quantity>2</Quantity> 
     <TotalAmount>6</TotalAmount> 
     <double-computation>6</double-computation> 
     <decimal-computation>6</decimal-computation> 
     </Item> 
    </Items> 
</results> 

同じ不正確さが他に存在します。

あなたがいhttp://xsltransform.net/94AbWBVを見れば

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs"> 

    <xsl:strip-space elements="*"/> 
    <xsl:output indent="yes"/> 

    <xsl:template match="/"> 
     <results> 
      <names-precise> 
      <xsl:value-of select="/Items/Item[((xs:decimal(Amount) * xs:integer(Quantity)) != TotalAmount)]/Name"/> 
      </names-precise> 
      <names-imprecise> 
       <xsl:value-of select="/Items/Item[((Amount * Quantity) != TotalAmount)]/Name"/> 
      </names-imprecise> 
      <xsl:apply-templates/> 
     </results> 

    </xsl:template> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Item"> 
     <xsl:copy> 
      <xsl:apply-templates/> 
      <double-computation> 
       <xsl:value-of select="Amount * Quantity"/> 
      </double-computation> 
      <decimal-computation> 
       <xsl:value-of select="xs:decimal(Amount) * xs:integer(Quantity)"/> 
      </decimal-computation> 
     </xsl:copy> 
    </xsl:template> 
</xsl:transform> 

あなたは十分ではありません使用するデフォルトの浮動小数点演算が正確な結果を計算することがわかりますIEEEダブルナンバーフォーマットを使用するJavascriptのような言語:

document.getElementById('result').textContent = 0.0012 * 17;
<p>Result of <code>0.0012 * 17</code> with Javascript is <code id="result"></code>.</p>

+0

ハイ・マーティン。ありがとう。魅力的な作品。 :) – Balu