每个迭代的动态XSLT
我有以下XML:每个迭代的动态XSLT,xslt,for-loop,Xslt,For Loop,我有以下XML: <bookstore> <author name="King"> <book id="book1"><title>Title1</title></book> <book id="book2"><title>Title2</title></book> <bo
<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>
标题1
标题2
标题3
标题4
然后我有一个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>
这对于每个循环都不起作用。我想在书上反复说明我做错了什么?如果您真的需要或想要使用字符串的动态XPath求值,那么您需要一个扩展函数,例如
…
如果您真的需要或想要使用字符串的动态XPath求值,那么您需要一个扩展函数,例如。..
虽然完整的动态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>
<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>
当此转换应用于提供的XML文档时:
<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>
<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>
标题1
标题2
标题3
标题4
生成所需的正确结果:
<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>
<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>
标题1
标题2
标题3
标题4
虽然完整的动态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>
<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>
当此转换应用于提供的XML文档时:
<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>
<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>
标题1
标题2
标题3
标题4
生成所需的正确结果:
<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>
<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>
标题1
标题2
标题3
标题4
问得好,+1。虽然在XPath 3.0/XSLT 3.0正式发布之前不可能对任何XPath表达式求值,但可以对有限的表达式集求值。好问题,+1。虽然在XPath 3.0/XSLT 3.0正式发布之前,不可能对任何XPath表达式求值,但可以对有限的表达式集求值。@VoodooRider:不客气。同时,我修复了一个格式问题,现在可以看到完整的代码了。@VoodooRider:不客气。同时,我修复了一个格式问题,现在完整的代码可见了。