请考虑以下代码:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template name="getServiceDef">
<services>
<service>
<serviceName>service</serviceName>
<parameters>
<param1/>
<param2/>
<param3/>
</parameters>
</service>
</services>
</xsl:template>
<xsl:template name="getInput">
<parameters>
<param1>10</param1>
<param2>single</param2>
<param3>2</param3>
<param4>650</param4>
<param5>750</param5>
</parameters>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="serviceDef">
<xsl:call-template name="getServiceDef"/>
</xsl:variable>
<xsl:variable name="inputParameters">
<xsl:call-template name="getInput"/>
</xsl:variable>
<xsl:for-each select="$inputParameters/parameters/param4">
<xsl:variable name="currentParameterName" select="./local-name()"/>
<xsl:choose>
<xsl:when test="$serviceDef/services/service/parameters/$currentParameterName">
<xsl:message>
$currentParameterName '<xsl:value-of select="$currentParameterName"/>'exists.
$serviceDef/services/service/parameters/param4 '<xsl:value-of select="$serviceDef/services/service/parameters/param4"/>'
$serviceDef/services/service/parameters/$currentParameterName '<xsl:value-of select="$serviceDef/services/service/parameters/$currentParameterName"/>'
</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:message>param '<xsl:value-of select="$currentParameterName"/>' does NOT exist</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
以行
开头的代码块<xsl:for-each select="$inputParameters/parameters/param4">
我试图决定,$ serviceDef中是否存在节点。它不是。但是,如果使用扩展变量执行XPATH查询,则查询将被评估为&#34;节点存在&#34; (下面的控制台输出)。
问题: 为何查询 $ serviceDef / services / service / parameters / param4返回&#34; False&#34;和 $ serviceDef / services / service / parameters / $ currentParameterName返回&#34; True&#34; ? 我希望查询完全相同。
要复制:
将上面的代码复制到文件stackOverFlowReplication.xsl
笔记本电脑:〜$ echo&#34;&lt; notneeded /&gt;&#34; &GT; sample.xml中
控制台输出:
No license file found - running with licensable features disabled
Warning at xsl:stylesheet on line 2 column 125 of stackOverFlowReplication.xsl:
Running an XSLT 10 stylesheet with an XSLT 20 processor
$currentParameterName 'param4'exists.
$serviceDef/services/service/parameters/param4 ''
$serviceDef/services/service/parameters/$currentParameterName 'param4'
答案 0 :(得分:1)
您似乎期望test="$serviceDef/services/service/parameters/$currentParameterName"
在运行时根据您在最后一步中插入的变量构造XPath表达式。这不会发生,您只需在最后一步中评估变量引用$currentParameterName
,并评估字符串param4
和布尔上下文中的任何非空字符串,如xsl:when/xsl:if test
评估为真。
您需要使用XSLT 3.0中提供的xsl:evaluate
进行动态XPath评估,或者对于您可以使用的简单案例,例如test="$serviceDef/services/service/parameters/*[local-name() = $currentParameterName]"
。
为了让您了解表达式的评估结果,请参阅http://xsltransform.net/naZXpX1
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs fo">
<xsl:template name="getServiceDef">
<services>
<service>
<serviceName>service</serviceName>
<parameters>
<param1/>
<param2/>
<param3/>
</parameters>
</service>
</services>
</xsl:template>
<xsl:template name="getInput">
<parameters>
<param1>10</param1>
<param2>single</param2>
<param3>2</param3>
<param4>650</param4>
<param5>750</param5>
</parameters>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="serviceDef">
<xsl:call-template name="getServiceDef"/>
</xsl:variable>
<xsl:variable name="inputParameters">
<xsl:call-template name="getInput"/>
</xsl:variable>
<xsl:for-each select="$inputParameters/parameters/param4">
<xsl:variable name="currentParameterName" select="./local-name()"/>
<xsl:variable name="exp1" select="$serviceDef/services/service/parameters/$currentParameterName"/>
<debug-help string-sequence-test="{$exp1 instance of xs:string*}" node-sequence-test="{$exp1 instance of node()*}" value="{$exp1}"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出<debug-help string-sequence-test="true" node-sequence-test="false" value="param4"/>
所以它显示你从来没有一个节点序列,只是一个带有你的变量值的单个字符串的序列。