我正在尝试使用XSLT 1.0执行一组存储在变量中的给定xpath。在模板中使用for-each访问xpath列表时,上下文会发生变化,因此无法从原始xml中提取任何xpath值。它只返回空值。
输入xml:
<catalog>
<book id="bk101">
<author>Gambardella Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
</book>
<book id="bk102">
<author>Ralls Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
</book>
</catalog>
XSLT我试过了:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dyn="http://exslt.org/dynamic" xmlns:exsl="http://exslt.org/common" version="1.0" exclude-result-prefixes="dyn exsl">
<xsl:variable name="newLine" select="'
'" />
<xsl:variable name="comma" select="','" />
<xsl:variable name="details">
<xpaths>
<xpath>/catalog/book/author</xpath>
<xpath>/catalog/book/title</xpath>
<xpath>/catalog/book/genre</xpath>
<xpath>/catalog/book/price</xpath>
<xpath>/catalog/book/publish_date</xpath>
</xpaths>
</xsl:variable>
<xsl:template match="/">
<xsl:apply-templates select="*" mode="extract" />
</xsl:template>
<xsl:template match="book" mode="extract">
<xsl:if test="position() !=1">
<xsl:value-of select="$newLine" />
</xsl:if>
<xsl:for-each select="exsl:node-set($details)/xpaths/xpath">
<xsl:if test="position() ! =1" />
<xsl:value-of select="$comma" />
<xsl:variable name="this" select="." />
<xsl:value-of select="dyn:evaluate($this)" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我期待的输出是:
Gambardella Matthew,XML Developer's Guide,Computer,44.95,2000-10-01
Ralls Kim,Midnight Rain,Fantasy,5.95,,
xslt以上的输出产生:
,,,,,
,,,,,
有人可以提供所需的XSLT 1.0的线索吗?提前谢谢。
答案 0 :(得分:1)
我不认为您使用的绝对XPath表达式在book
元素的上下文中有意义,您需要使用相对路径。然后,您可以按如下方式更改本书的上下文:
<xsl:variable name="details">
<xpaths>
<xpath>author</xpath>
<xpath>title</xpath>
<xpath>genre</xpath>
<xpath>price</xpath>
<xpath>publish_date</xpath>
</xpaths>
</xsl:variable>
<xsl:template match="/">
<xsl:apply-templates select="*" mode="extract" />
</xsl:template>
<xsl:template match="book" mode="extract">
<xsl:if test="position() !=1">
<xsl:value-of select="$newLine" />
</xsl:if>
<xsl:variable name="book" select="."/>
<xsl:for-each select="exsl:node-set($details)/xpaths/xpath">
<xsl:if test="position() != 1">
<xsl:value-of select="$comma" />
</xsl:if>
<xsl:variable name="path" select="." />
<xsl:for-each select="$book"><xsl:value-of select="dyn:evaluate($path)" /></xsl:for-each>
</xsl:for-each>
</xsl:template>
显然,如果您只是使用$book/*[local-name() = $path]
,则可以在不使用通常不受支持的dyn:evaluate
的情况下使其工作。