[英]XPath - Java XPath result unexpected
I have noticed something strange. 我注意到了一些奇怪的事情。 This is my XML
这是我的XML
<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>
And this is the XPath that I used 这是我使用的XPath
/Items/Item[((Amount * Quantity) != TotalAmount)]/Name
/ Items / Item [(((Amount * Quantity)!= TotalAmount)] /名称
This XPath had to print the name of the item whose TotalAmount!= Product( Amount, Quantity ). 此XPath必须打印其TotalAmount!= Product( Amount,Quantity )的项目的名称。
I get the value A. But I do not understand why this is happening Because 0.0012 * 17 = 0.0204 我得到值A。但是我不明白为什么会这样,因为0.0012 * 17 = 0.0204
And if I remove Item 'A', then I do not get a result. 而且,如果我删除项目“ A”,那么我不会得到结果。
The same goes for newer versions of XPath as well 新版本的XPath也是如此
for $x in /Items/Item[((Amount * Quantity) != TotalAmount)] return $x/Name
/ Items / Item [(((Amount * Quantity)!= TotalAmount)]中的$ x返回$ x / Name
I'm using Saxon 9 in Java. 我在Java中使用Saxon 9。
Can someone explain why this is happening. 有人可以解释为什么会这样。
Try using xs:decimal
/ xs:integer
for better precision: /Items/Item[((xs:decimal(Amount) * xs:integer(Quantity)) != TotalAmount)]/Name
. 尝试使用
xs:decimal
/ xs:integer
以获得更高的精度: /Items/Item[((xs:decimal(Amount) * xs:integer(Quantity)) != TotalAmount)]/Name
。
If you look at http://xsltransform.net/94AbWBV which does 如果您查看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>
you can see that the default floating point arithmetic used does not suffice to compute the exact result: 您会看到所使用的默认浮点算法不足以计算出准确的结果:
<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>
The same imprecision exists in other language like Javascript using the IEEE double number format: 在其他语言(例如使用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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.