expression must evaluate to a node set 是什么意思?

What does expression must evaluate to a node set mean?

我有以下代码。

 <!-- Error func -->
 <xsl:template name="myFunc">
    <xsl:param name="person"/>
    <xsl:variable name="name">
       "name": "<xsl:value-of select="$person/name"/>",
    </xsl:variable>
    <xsl:value-of select="$name"/>
 </xsl:template>

 <!-- Call function -->
 <xsl:template match="/">
    <xsl:call-template name="myFunc">
        <xsl:with-param name="person" select="list/person"/>
    </xsl:call-template>
 </xsl:template>

我正在将变量用于更复杂的事情,但到目前为止我什至无法让这一点工作。有什么理由吗?我不断收到以下错误

System.Xml.Xsl.XslTransformException
  HResult=0x80131942
  Message=Expression must evaluate to a node-set.
  Source=System.Private.Xml
  StackTrace:
   at System.Xml.Xsl.Runtime.XsltConvert.EnsureNodeSet(IList`1 listItems)
   at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results)
   at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer)
   at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, XmlWriter results, XmlResolver documentResolver)
   at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, XmlWriter results)
   at WZDxConversion.Controllers.ValuesController.Post() in --------------------------------------------------------
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()

我不确定你为什么会收到此代码片段的错误,但我可以告诉你错误消息的含义。

当您使用 $X/Y 等路径表达式时,“/”运算符左侧的表达式必须计算为一个节点集,它是少数XSLT 1.0 和 XPath 1.0 中的基本数据类型。 (还有一些其他地方的值必须是节点集,但“/”的lhs是最常见的。)

当您使用没有 select 属性的 xsl:variable 时,例如

<xsl:variable name="v">
  <a><b/></a>
</xsl:variable>

那么 v 的值不是节点集,而是 "result tree fragment",这意味着 $v 不能用在“/”运算符的 lhs 上。

这是 XSLT 1.0 中的一个严重设计错误。 James Clark 在这里解释了基本原理:https://markmail.org/message/uafk4pxqawkjuaid

这意味着 XSL WG 预计 XSLT 1.0 之后会很快出现解除此类限制的 XSLT 1.1;他们从没想过 20 多年后还有人在使用 XSLT 1.0。在 XSLT 2.0 中当然取消了限制,但 Microsoft 从未实现它。