XSL无效类型错误-使用的值设置变量



我正在尝试获取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

对于<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>

变量类型是包含具有由内部CCD_ 8选择的第一节点的字符串值的文本节点的结果树片段。对于结果树片段类型的变量,您不能进行任何XPath导航,可以使用value-of输出其字符串值,或者使用copy-of输出其树片段。如果要进行XPath导航,则首先需要使用exsl:node-set或类似方法将结果树片段转换为节点集,但即使对第二个示例进行了转换,使用exsl:node-set($deal)也会得到一个节点集,其中包含一个包含文本节点的文档节点。因此,如果您希望在XSLT1.0中有一个包含节点的变量,则需要使用

<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"/>

一些XSLT1.0处理器(尤其是.NET框架中IE或Edge和XslTransform使用的各种MSXML版本)不支持exsl:node-set,而是在专有名称空间(即<xsl:variable name="deal" select="ms:node-set($deal-rtf)" xmlns:ms="urn:schemas-microsoft-com:xslt"/>)中支持类似的功能。

xsl:variable内部,您当然可以使用xsl:choose,例如

<xsl:variable name="deal-rtf">
  <xsl:choose>
     <xsl:when test="...">
       <xsl:copy-of select="/webpage/results/cars/*[partner_name = $company_name and vehicle_class_description = $vehicle_class_description_full and pay_now = 'Y']"/>
     </xsl:when>
     <xsl:otherwise>
        <xsl:copy-of select="webpage/results/cars/*[partner_name = $company_name and vehicle_class_description = $vehicle_class_description_full]"/>
     </xsl:otherwise>
  </xsl:choose>
</xsl:variable>
<xsl:variable name="deal" select="exsl:node-set($deal-rtf)" xmlns:exsl="http://exslt.org/common"/>
<xsl:value-of select="$deal/total_price"/>

问题是第二个版本返回的是RTF(Resulting Tree Fragment),而不是像第一个版本那样的节点集。XPath查询不能应用于RTF,只能应用于节点集。

有关差异的解释,请访问Oracle。

在XSLT-1.0中,您无法避免这种情况,就像StackOverflow中所解释的那样。

我引用Oracle链接:

结果树片段相当于只包含根节点的节点集
不能在结果树片段上应用诸如"/"、"//"或谓词之类的运算符。它们仅适用于节点集数据类型。

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

正如其他人所说,只有使用xsl:variable标记中的内联select属性才能生成可用的节点集。

但是,您不必使用更高版本的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)]"/>

其中CCD_ 23是不是被测试的XML数据的直接部分的变量。

如果选择太多,它可能会变得笨拙,但可以通过测试每个备选方案来减轻这种情况,以确保它只在需要时生成一个节点集,否则为空。然后简单地将它们放在select中,它们之间有一个|

相关内容

  • 没有找到相关文章

最新更新