每次迭代的动态XSLT



我有以下XML:

<bookstore>
        <author name="King">
              <book id="book1"><title>Title1</title></book>
              <book id="book2"><title>Title2</title></book>
              <book id="book3"><title>Title3</title></book>
              <book id="book4"><title>Title4</title></book>
        </author>
</bookstore>

则有一个XSLT模板,如:

<xsl:template>
    <xsl:param name="booksPath" select="'bookstore/author/book'"/>
    <xsl:for-each select="*[local-name() = $booksPath]">
         <p><xsl:value-of select="title" /></p>
    </xsl:for-each>
</xsl:template>

和for-each循环不起作用。我想对书进行迭代我做错了什么?

如果您真的需要或想要使用动态XPath计算字符串,那么您需要像saxon:evaluate这样的扩展函数,例如<xsl:for-each select="saxon:evaluate($booksPath)" xmlns:saxon="http://saxon.sf.net/">...</xsl:for-each> .

虽然完全动态XPath求值不是XSLT 1.0/XPath 1.0或XSLT 2.0/XPath 2.0的一部分,但是可以生成以相当有限的方式工作的XSLT 1.0实现:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:template match="/">
   <xsl:variable name="vrtfEvalResult">
     <xsl:call-template name="eval">
       <xsl:with-param name="pPath" select="'/bookstore/author/book'"/>
     </xsl:call-template>
   </xsl:variable>
  <xsl:for-each select="ext:node-set($vrtfEvalResult)/*">
    <p><xsl:value-of select="title" /></p>
  </xsl:for-each>
 </xsl:template>
 <xsl:template match="text()"/>
 <xsl:template match="Path" name="eval">
  <xsl:param name="pPath" select="."/>
  <xsl:param name="pContext" select="/"/>
  <xsl:choose>
   <!-- If there is something to evaluate -->
   <xsl:when test="string-length($pPath) >0">
      <xsl:variable name="vPath" select=
          "substring($pPath,2)"/>
      <xsl:variable name="vNameTest">
       <xsl:choose>
        <xsl:when test="not(contains($vPath, '/'))">
         <xsl:value-of select="$vPath"/>
        </xsl:when>
        <xsl:otherwise>
         <xsl:value-of select=
             "substring-before($vPath, '/')"/>
        </xsl:otherwise>
       </xsl:choose>
      </xsl:variable>
      <xsl:call-template name="eval">
       <xsl:with-param name="pPath" select=
         "substring-after($pPath, $vNameTest)"/>
       <xsl:with-param name="pContext" select=
        "$pContext/*[name()=$vNameTest]"/>
      </xsl:call-template>
  </xsl:when>
  <!-- Otherwise we have evaluated completely the path -->
  <xsl:otherwise>
   <xsl:copy-of select="$pContext"/>
  </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

,当对提供的XML文档应用此转换:

<bookstore>
    <author name="King">
        <book id="book1">
            <title>Title1</title>
        </book>
        <book id="book2">
            <title>Title2</title>
        </book>
        <book id="book3">
            <title>Title3</title>
        </book>
        <book id="book4">
            <title>Title4</title>
        </book>
    </author>
</bookstore>

生成所需的正确结果:

<p>Title1</p>
<p>Title2</p>
<p>Title3</p>
<p>Title4</p>

最新更新