Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 使用xsl:for-each中的current()检索超出for-each范围的节点时出现问题_Xslt_Xpath_Foreach - Fatal编程技术网

Xslt 使用xsl:for-each中的current()检索超出for-each范围的节点时出现问题

Xslt 使用xsl:for-each中的current()检索超出for-each范围的节点时出现问题,xslt,xpath,foreach,Xslt,Xpath,Foreach,您好,我是XSLT2.0的初学者,但由于最近的一个项目需要XML配置,所以我想尝试一下。 XML结构如下所示: <bookstore> <books> <book author="a" title="a1"/> <book author="b" title="b1"/> <book author="c" title="c1"/> <book author="d" title="d1"/> &l

您好,我是XSLT2.0的初学者,但由于最近的一个项目需要XML配置,所以我想尝试一下。 XML结构如下所示:

<bookstore>
<books>
    <book author="a" title="a1"/>
    <book author="b" title="b1"/>
    <book author="c" title="c1"/>
    <book author="d" title="d1"/>
</books>
<topAuthorList>
    <thisMonth>c,a,d,b</thisMonth>
</topAuthorList>
    <xsl:template match="/bookstore">
    <result>
        <xsl:variable name="varList">
            <xsl:value-of select="topAuthorList/thisMonth"></xsl:value-of>
        </xsl:variable> 

        <test>
            <xsl:value-of select="books/book[@author='a']/@title"></xsl:value-of>
        </test>

        <books>
            <xsl:for-each select="tokenize($varList, ',')">
                <xsl:value-of select="books/book[@author=current()]/@title"></xsl:value-of>
            </xsl:for-each>
        </books>
    </result>
</xsl:template>
我在谷歌和这个网站上搜索了很多次,都找不到答案。我甚至尝试过使用调用模板,也就是说,将当前作为参数传递,并让第二个模板处理节点选择,但仍然存在相同的错误。

此方法有效:

  <xsl:template match="/bookstore">
    <result>
      <xsl:variable name="varList">
        <xsl:value-of select="topAuthorList/thisMonth"></xsl:value-of>
      </xsl:variable> 

      <test>
        <xsl:value-of select="books/book[@author='a']/@title"></xsl:value-of>
      </test>

      <books>
        <xsl:variable name="books" select="/bookstore/books"/>
        <xsl:for-each select="tokenize($varList, ',')">
          <xsl:value-of select="$books/book[@author=current()]/@title"></xsl:value-of>
        </xsl:for-each>
      </books>
    </result>
  </xsl:template>
我所做的只是将/bookstore/books放在一个变量中,然后从该变量进行查找。我有一个直观的理解为什么这是必要的,但没有一些研究没有确切的正式原因。也许这里的其他XML专家可以插话

编辑:我在Michael Kay出色的XSLT 2.0和XPath 2.0巨著中找到了相关信息,第625页:

根路径表示一条路径 从树的根节点开始 包含上下文节点的

由于您案例中的上下文节点是一个裸字符串,因此它不包含您要查找的节点。使用变量可以为XPath表达式提供适当的上下文。

我想您需要:

        <books>
            <xsl:variable name="tokens" select="tokenize($varList, ',')"/>
            <xsl:value-of select="
                for $a in $tokens 
                return books/book[@author=$a]/@title"/>
        </books>
编写时,books是child::books的缩写,即作为上下文项的子项的books元素。但是上下文项是什么?包含xsl:for each的将上下文项设置为在其select表达式中选择的每个项。但这是对tokenize的调用,因此上下文项是字符串,而字符串没有子项

当您深入到层次结构中时,上下文项的概念非常有用。当您进行连接时,它没有用处。对于连接,您需要变量。有时,你可以通过使用。作为其中一个变量,当前作为另一个变量,但当它用完蒸汽时,您需要真正命名的变量


顺便说一句,除非您真的想创建一个新的文档树,否则请不要将的xsl:value用作xsl:variable的子级。您几乎可以肯定地重写varlist的声明,因为它不仅可以减少代码编写量,而且效率更高,因为它避免了构建新树的需要。

这听起来有点棘手,但却让我避免了数小时的绊脚石。但如何解释呢?为什么它必须是一个变量?它与测试节点有什么区别?是的,这也是有意义的,因为序列是封装的。在第一个解决方案中使用position也会起作用。在您的解决方案中,是否可以返回模板化值,如添加标记或分隔符?我不知道您的意思。你能扩大一点吗?
        <books>
            <xsl:variable name="tokens" select="tokenize($varList, ',')"/>
            <xsl:value-of select="
                for $a in $tokens 
                return books/book[@author=$a]/@title"/>
        </books>