我想创建一个包含动态名称和模式名称的变量数组。 同样,这些变量是一条逐步处理document-node()的链。 所以不要这样写:
<xsl:variable name="A">
<xsl:apply-templates mode="A" select="."/>
</xsl:variable>
<xsl:variable name="B">
<xsl:apply-templates mode="B" select="$A"/>
</xsl:variable>
<xsl:variable name="C">
<xsl:apply-templates mode="C" select="$B"/>
</xsl:variable>
我想做这样的事情:
<xsl:variable name="mode-names" select="'A', 'B', 'C'"/>
<xsl:variable name="vars">
<xsl:for-each select="$mode-names">
<xsl:variable name="pos" select="position()" />
<xsl:variable name="{.}">
<xsl:apply-templates mode="{.}" select="if ($pos=1) then . else $modi[$pos -1]"/>
</xsl:variable>
</xsl:for-each>
</xsl:variable>
错误消息:无效的变量名称:无效的QName {{。}}
xslt 3.0
答案 0 :(得分:1)
目前尚不清楚以后如何使用xsl:variable name="{.}"
,如果要在变量中存储多个项目,则当然可以使用一系列项目,因此对于您创建您可以使用document-node()*
类型的变量来表示各种文档节点,该变量表示一系列文档/文档节点。
因此,使用三个(静态)模式并把每个结果作为项目存储在该变量中的示例将是
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output indent="yes"/>
<xsl:mode name="A" on-no-match="shallow-copy"/>
<xsl:template match="foo" mode="A">
<bar>
<xsl:apply-templates mode="#current"/>
</bar>
</xsl:template>
<xsl:mode name="B" on-no-match="shallow-copy"/>
<xsl:template match="bar" mode="B">
<whatever>
<xsl:apply-templates mode="#current"/>
</whatever>
</xsl:template>
<xsl:mode name="C" on-no-match="shallow-copy"/>
<xsl:template match="text()" mode="C">
<xsl:value-of select="upper-case(.)"/>
</xsl:template>
<xsl:variable name="results" as="document-node()*">
<xsl:variable name="r1">
<xsl:apply-templates mode="A"/>
</xsl:variable>
<xsl:sequence select="$r1"/>
<xsl:variable name="r2">
<xsl:apply-templates select="$r1" mode="B"/>
</xsl:variable>
<xsl:sequence select="$r2"/>
<xsl:apply-templates select="$r2" mode="C"/>
</xsl:variable>
<xsl:template match="/">
<results>
<xsl:for-each select="$results">
<result step="{position()}">
<xsl:copy-of select="."/>
</result>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/3NJ38YX/1
正如我在评论中已经说过的那样,除非在运行时构造整个样式表然后使用transform
函数运行它,否则无法在运行时构造模式名称:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:axsl="http://www.w3.org/1999/XSL/Transform-alias"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="mode-names" as="xs:string*" select="'A', 'B', 'C'"/>
<xsl:param name="stylesheet-template-string" as="xs:string"><![CDATA[
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="3.0" exclude-result-prefixes="#all">
<xsl:mode name="A" on-no-match="shallow-copy"/>
<xsl:template match="foo" mode="A">
<bar>
<xsl:apply-templates mode="#current"/>
</bar>
</xsl:template>
<xsl:mode name="B" on-no-match="shallow-copy"/>
<xsl:template match="bar" mode="B">
<whatever>
<xsl:apply-templates mode="#current"/>
</whatever>
</xsl:template>
<xsl:mode name="C" on-no-match="shallow-copy"/>
<xsl:template match="text()" mode="C">
<xsl:value-of select="upper-case(.)"/>
</xsl:template>
</xsl:stylesheet>
]]></xsl:param>
<xsl:param name="stylesheet-template" select="parse-xml($stylesheet-template-string)"/>
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:mode name="construct-stylesheet" on-no-match="shallow-copy"/>
<xsl:variable name="stylesheet">
<xsl:apply-templates select="$stylesheet-template" mode="construct-stylesheet"/>
</xsl:variable>
<xsl:template match="xsl:stylesheet | xsl:transform" mode="construct-stylesheet">
<xsl:copy>
<xsl:apply-templates select="@* , node()" mode="#current"/>
<axsl:variable name="results" as="document-node()*">
<xsl:iterate select="$mode-names">
<axsl:variable name="result-{.}">
<axsl:apply-templates select="{if (position() eq 1) then '.' else '$result-' || subsequence($mode-names, position() - 1, 1)}" mode="{.}"/>
</axsl:variable>
<axsl:sequence select="$result-{.}"/>
</xsl:iterate>
</axsl:variable>
<axsl:template match="/">
<results>
<axsl:for-each select="$results">
<result step="{{position()}}">
<axsl:copy-of select="."/>
</result>
</axsl:for-each>
</results>
</axsl:template>
</xsl:copy>
</xsl:template>
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:sequence
select="transform(map {
'source-node' : .,
'stylesheet-node' : $stylesheet
})?output"/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/3NJ38YX/2用于一种模式,而https://xsltfiddle.liberty-development.net/3NJ38YX/3用于不同的模式。
该示例具有一个独立的间接关系,要使用的样式表作为字符串参数传入,但可以或当然可以作为文档节点传入,或使用{{1}从文件解析}的功能相同。