Xslt 使用xsl:for-each中的current()检索超出for-each范围的节点时出现问题
您好,我是XSLT2.0的初学者,但由于最近的一个项目需要XML配置,所以我想尝试一下。 XML结构如下所示: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
<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>