2017-02-23 14 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

/Items/Item[((xs:decimal(Amount) * xs:integer(Quantity)) != TotalAmount)]/Name 더 나은 정밀도를 위해 xs:decimal/xs:integer을 사용해보세요.

<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 double number 형식을 사용하는 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