我正试图使用XSLT1.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)
我的主要问题是应该如何处理输入文件中的百分比符号。
我不知道这段代码是如何生成NaN的。它不做任何算术运算,这就是NaN的来源。当我运行它时,它会生成以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<MyItem/>
请检查您是否正在运行您所说的代码,如果它真的提供了NaN,请向我们提供您如何运行它的详细信息(例如,哪个处理器以及如何调用)。
这段代码显然是无稽之谈——模板isNaN是用"item"元素作为上下文节点调用的,它试图找到名为"item"的上下文节点的子节点,当然没有这样的子节点。但这应该不会带来任何回报,而不是NaN。
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(正如我们现在所知),它不等于任何东西。如果您想将值视为字符串,并且由于某种原因,它首先转换为数字,因此您可以通过执行字符串(项)显式强制转换它,而不是您想要的值。最后,如果你只想检查这个值是否是一个有效的数字,你可以使用上面的技巧:
<xsl:value-of select="number($item) = $item"/>
如果该值不能转换为数字,则数字($item)将返回NaN(正如我们所知,它不等于任何值),这意味着该项不是有效值。如果$item可以转换为数字,则'='的另一侧将隐式转换为数字并且两者应具有相同的值,从而返回真正的
显而易见的问题是,所提供的代码正在调用当前节点为item
:的模板
<xsl:template name="IsNaN">
<MyItem>
<xsl:variable name="myItem" select="item" />
<xsl:value-of select="$myItem"/>
</MyItem>
</xsl:template>
这将尝试输出当前节点的第一个item
子级的字符串值,但是在所提供的XML文档中,item
本身没有item
子级。
当然,这并不能解释为什么返回NaN——任何兼容的XSLT处理器都必须生成空字符串。我相信您的实际代码与您向我们展示的代码不同,实际代码涉及算术运算。在这种情况下,表达式的求值尝试将空字符串转换为数字,结果是NaN。
只需像这样重写上面的模板:
<xsl:template name="IsNaN">
<MyItem>
<xsl:value-of select="."/>
</MyItem>
</xsl:template>