动态XSLT for-each迭代

时间:2011-09-16 10:35:52

标签: xslt for-loop

我有以下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循环不起作用。我想迭代书籍我做错了什么?

2 个答案:

答案 0 :(得分:1)

如果您真的需要或想要从字符串中使用动态XPath评估,那么您需要一个类似saxon:evaluate的扩展功能,例如<xsl:for-each select="saxon:evaluate($booksPath)" xmlns:saxon="http://saxon.sf.net/">...</xsl:for-each>

答案 1 :(得分:1)

虽然完整的动态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>