XSL无效类型错误 - 使用Value-of设置变量

时间:2016-05-04 14:55:45

标签: xml xslt xpath xslt-1.0

我想获得value-of $deal/total_price。在第一个街区,我能够获得价值,一切都很好。在我使用value-of设置名为deal的变量的第二个块中,尝试显示$deal/total_price时出错。如何在第二个块中使用设置返回$deal/total_price

使用:

<xsl:variable name="deal" select="/webpage/results/cars/*[partner_name = $company_name and vehicle_class_description = $vehicle_class_description_full]" />        
<xsl:value-of select="$deal/total_price"/>

不起作用:

<xsl:variable name="deal">
    <xsl:value-of select="/webpage/results/cars/*[partner_name = $company_name and vehicle_class_description = $vehicle_class_description_full]"/>
</xsl:variable>
<xsl:value-of select="$deal/total_price"/>

我收到以下错误/警告:

Warning: XSLTProcessor::transformToXml(): Invalid type
Warning: XSLTProcessor::transformToXml(): runtime error:
Warning: XSLTProcessor::transformToXml(): XPath evaluation returned no result

3 个答案:

答案 0 :(得分:1)

使用<xsl:variable name="deal" select="/webpage/results/cars/*[partner_name = $company_name and vehicle_class_description = $vehicle_class_description_full]" />,通过计算select XPath表达式来定义变量类型,该表达式返回XSLT / XPath 1.0中的节点集。然后,您可以在节点集上执行XPath导航,例如选择子节点。

<xsl:variable name="deal">
    <xsl:value-of select="/webpage/results/cars/*[partner_name = $company_name and vehicle_class_description = $vehicle_class_description_full]"/>
</xsl:variable>

变量类型是包含文本节点的结果树片段,该文本节点具有由内部value-of选择的第一个节点的字符串值。使用类型结果树片段的变量,您无法执行任何XPath导航,您可以使用value-of或使用copy-of的树片段输出其字符串值。如果你想进行XPath导航,那么首先需要使用exsl:node-set或类似的方法将结果树片段转换为节点集,但即使你为第二个样本执行此操作,也可以使用{{1}具有包含文本节点的文档节点的节点集。因此,如果您想在XSLT 1.0中拥有包含节点的变量,则需要使用

exsl:node-set($deal)

某些XSLT 1.0处理器(特别是IE或Edge使用的各种MSXML版本以及.NET框架中的<xsl:variable name="deal-rtf"> <foo> <bar>...</bar> </foo> </xsl:variable> <xsl:variable name="deal" select="exsl:node-set($deal-rtf)" xmlns:exsl="http://exslt.org/common"/> <xsl:value-of select="$deal/foo/bar"/> )不支持XslTransform,而是支持专有命名空间中的类似功能(即exsl:node-set)。

<xsl:variable name="deal" select="ms:node-set($deal-rtf)" xmlns:ms="urn:schemas-microsoft-com:xslt"/>内,您当然可以使用xsl:variable,例如

xsl:choose

答案 1 :(得分:0)

问题是第二个版本返回RTF(结果树片段)而不是第一个版本的节点集。 XPath查询无法应用于RTF,只能应用于节点集。

对差异的解释can be found here at Oracle.

在XSLT-1.0中,您无法避免这种情况,例如explained here at StackOverflow

我引用了Oracle链接:

  

结果树片段相当于仅包含根节点的节点集     您不能在结果树片段上应用“/”,“//”或谓词等运算符。它们仅适用于节点集数据类型。

(可能最简单的)解决方案是使用XSLT-2.0,因为在XSLT-2.0中,所有变量都是节点集,并且RTF已经消失。

答案 2 :(得分:0)

就像其他人所说的那样,可用的节点集只能通过使用select标记中的内联xsl:variable属性来产生。

但是,您不必使用更高版本的XSLT或特定的XSLT扩展,这在共享主机上可能是不可能的。

为迎合备用节点集,诀窍是使用|联合运算符加入每个备用节点集,但要确保[ ]内不需要的备用节点的条件不返回任何节点。

测试不必依赖于[ ]所附加的元素,但是可以使用所需的任何变量和文字来确保替代方法仅生成具有其自身唯一条件的节点集。 ,其他人则永远不会。

为了在上面的评论中举例说明您的示例,

<xsl:value-of select="/webpage/results/cars/*[($access_type = 'web') and (partner_name = $company_name) and (vehicle_class_description = $vehicle_class_description_full) and (pay_now = 'Y')]|/webpage/results/cars/*[($access_type = 'phone') and (partner_name = $company_name) and (vehicle_class_description = $vehicle_class_description_full)]"/>

其中$web_access是一个变量,不直接属于要测试的XML数据。

如果选择太多,可能会变得笨拙,但是可以通过测试每个替代项以确保仅在需要时才生成节点集来缓解此问题,否则将其清空。然后只需将它们在select中插入,并在它们之间插入|

相关问题