有条件地设置变量而不切割祖先轴

Setting a variable conditionally with no cut of ancestor axis

我在 .NET 下有 xslt/xpath v1.0 堆栈。

我想有条件地设置变量 $myVar:

 <xsl:variable name="myVar">
   <xsl:if test="$case ='1'">
     <xsl:copy-of select="$otherVarA/down/the/rabbit/hole"/>
   </xsl:if>
  <xsl:if test="$case ='2'">
     <xsl:copy-of select="$otherVarB/down/the/rabbit/hole"/>
   </xsl:if>
   <xsl:if test="$case ='3'">
     <xsl:copy-of select="$otherVarC/down/the/rabbit/hole"/>
   </xsl:if>        
 </xsl:variable>

稍后有向下访问:$myVar/go/deeper 但也有向上访问,如 $myVar/ancestor::rabbit.

显然 <xsl:copy-of select="$myVar/down/to/rabbit/hole"/> 切断了向上的路径。

如何设置 $myVar 方式以访问祖先轴?

我知道<xsl:variable name=... select=...不会切割向上的轴。

您遇到的第一个问题是,在 XSLT 1.0 中,当您在变量中使用 xsl:copy-of 时,变量本身将是 "Result Tree Fragment" 类型,因此您将无法在其上使用 $myVar/down/to/rabbit/hole 之类的 xpath 表达式。您需要使用 "node-set" 扩展函数将其从结果树片段转换为可以访问其中节点的节点集(有关详细信息,请参阅 https://www.xml.com/pub/a/2003/07/16/nodeset.html)。

但是,这不会解决您的主要问题,关于获得祖先。因为您正在使用 xsl:copy-of,您将只能访问您已复制的节点,而不能访问它们在原始 XML 中未被复制的任何祖先节点。

我怀疑您的实际情况可能更复杂,但鉴于您在问题中显示的内容,您可以这样定义变量:

 <xsl:variable name="myVar"
               select="$otherVarA[$case ='1']/down/the/rabbit/hole
                       |$otherVarB[$case ='2']/down/the/rabbit/hole
                       |$otherVarC[$case ='3']/down/the/rabbit/hole"/>

这样,您现在引用原始 XML 中的节点,而不是制作副本,因此您不需要节点集函数,并且祖先函数可以访问中的所有祖先原来的XML.

这确实假设您的 $otherVarA/B/C 变量是对原始 XML 的引用,而不是使用 xsl:copy-of 创建的结果树片段。

有关人为的示例,请参阅 http://xsltfiddle.liberty-development.net/bwdwrw