请考虑以下代码:
<?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 查询,则查询将评估为"节点存在"(下面的控制台输出(。
问题:为什么要查询$serviceDef/services/service/parameters/param4 返回 "False" 和$serviceDef/服务/服务/参数/$currentParameterName返回"True" ?我希望查询是相同的。
要复制:
将上面的代码复制到文件堆栈OverFlowReplication.xsl
笔记本电脑:~$ 回显"><不需要 />">样本.xml
- laptop:~$ java -jar saxon9pe.jar -s:sample.xml -xsl:stackOverFlowReplication.xsl
控制台输出:
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'
您似乎希望test="$serviceDef/services/service/parameters/$currentParameterName"
根据您在最后一步中插入的变量在运行时构造 XPath 表达式。这不会发生,您只需在最后一步中计算变量引用$currentParameterName
,它就会计算为字符串param4
和布尔上下文中的任何非空字符串,例如xsl:when/xsl:if test
的计算结果为 true。
您需要使用 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"/>
,因此它表明您永远不会有节点序列,而只是带有变量值的单个字符串序列。