0

我正在尝试使用 XSLT 1.0 解析文档以插入数据库,并且我注意到一个问题,即任何时候我有一个 % 值,它将返回为“NaN”而不是实际值。我找不到解决此问题的任何地方

资源:

<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="NaNValues.xsl" ?>
<items>
    <item>10%</item> 
</items>

模板:

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

<xsl:template match="items">
 <xsl:for-each select="item">
  <xsl:call-template name="IsNaN"/>
 </xsl:for-each>
</xsl:template>

<xsl:template name="IsNaN">
 <MyItem>
   <xsl:variable name="myItem" select="item" />
   <xsl:value-of select="$myItem"/>
 </MyItem>
</xsl:template>
</xsl:stylesheet>

输出:

<MyItem>NaN</MyItem>

我尝试了以下方法:

substring($myItem,1,2)
substring($myItem,1,3)
concat($myItem,'')
string($myItem)

我的主要问题是应该如何处理我的输入文件中的百分比符号。

4

3 回答 3

2

我看不出这段代码如何产生 NaN。它不做任何算术运算,这就是 NaN 的来源。当我运行它时,它会产生这个:

<?xml version="1.0" encoding="UTF-8"?>
<MyItem/>

请检查您是否正在运行您说您正在运行的代码,如果它确实给出了 NaN,请向我们提供您如何运行它的详细信息(例如,哪个处理器,以及如何调用)。

代码显然是胡说八道——模板 isNaN 以“item”元素作为上下文节点调用,它试图找到名为“item”的上下文节点的子节点,当然没有这样的子节点。但这不应该返回任何内容,而不是 NaN。

于 2012-09-28T21:52:41.497 回答
2

NaN 永远不等于任何东西——甚至不等于它自己。因此,如果您有两个 NaN 值,它们将不相等。您可以通过对任何有效的 xml 文件运行这个小型 xslt 转换来检查这一点:

<xsl:template match="/">
      <xsl:value-of select="'3%' = '3%'"/>|<xsl:value-of select="number('3%') = number('3%')"/>
</xsl:template>

结果是:

true|false

number('3%') 试图将 '3%' 转换为无效的数字并导致 NaN。因此,在第二种情况下,NaN = NaN 有效,如您所见,这是错误的。

回到你的情况——这取决于你想用这个值做什么。如果您尝试在任何数学运算(加法、乘法等)中盲目使用它,xslt 处理器将尝试将您的值转换为数字(由于 % 字符而为 NaN),并且从此时起任何数学运算的结果将是 NaN(我们现在知道)不等于任何东西。如果您想将值视为字符串,并且由于某种原因首先转换为数字,那么您可以通过执行 string(item) 来显式转换它而不是您想要的字符串。最后,如果您只想检查该值是否是有效数字,您可以使用上面的技巧并执行以下操作:

<xsl:value-of select="number($item) = $item"/>

如果该值不能转换为数字,则 number($item) 返回 NaN(正如我们所知,它不等于任何值)意味着该项目不是有效值。如果 $item 可以转换为数字,则 '=' 的另一侧将隐式转换为数字,并且两者应具有相同的值,从而返回 true

于 2012-09-28T22:01:41.747 回答
1

明显的问题是提供的代码使用当前节点调用此模板item

<xsl:template name="IsNaN">
 <MyItem>
   <xsl:variable name="myItem" select="item" />
   <xsl:value-of select="$myItem"/>
 </MyItem>
</xsl:template>

这会尝试输出当前节点的第一item 个子节点的字符串值——但是在提供的 XML 文档中 anitem本身没有item子节点。

当然,这并不能解释返回 NaN 的原因——任何兼容的 XSLT 处理器都必须生成空字符串。我相信您的实际代码与您向我们展示的代码不同,实际代码涉及算术运算。在这种情况下,表达式的求值尝试将空字符串转换为数字——结果为 NaN。

只需像这样重写上面的模板

<xsl:template name="IsNaN">
 <MyItem>
    <xsl:value-of select="."/>
 </MyItem>
</xsl:template>
于 2012-09-29T13:52:18.130 回答