Xml 通过动态名称引用XSLT变量
我遇到了一个小问题 XSL文件:Xml 通过动态名称引用XSLT变量,xml,xslt,Xml,Xslt,我遇到了一个小问题 XSL文件: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions"> <xsl:template match="/"> <xsl:variab
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:template match="/">
<xsl:variable name="unumericValue" select="10" />
<xsl:variable name="uanotherValue" select="8" />
<xsl:for-each select="/root/try">
<xsl:value-of select="var" />
<xsl:variable name="min"><xsl:value-of select="@minimum" /></xsl:variable>
<xsl:value-of select="@type" />
<xsl:variable name="referenceName"><xsl:value-of select='concat("u",var)' /></xsl:variable>
<xsl:value-of select="$referenceName" />
<xsl:if test='$referenceName > $min'>
<p>Do something.</p>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="q1.xsl"?>
<root>
<try type="compare" minimum="9">
<var>numericValue</var>
<something>...</something>
</try>
<try type="compare" minimum="10">
<var>anotherValue</var>
<something>...</something>
</try>
</root>
如您所见,XML文件有两个var元素,它们应该与XSLT文件中的变量相匹配。但是我不知道哪种语法是正确的。
$referenceName只是我要使用的变量的名称。但我不知道如何将名称引用到现有变量。$referenceName不是对名为unumericValue或其他名称的变量的引用。它只是字符串值unumericValue,等等。因此它永远不会大于$min。但是,通过一点额外的工作,有一个技巧可以通过变量名查找变量:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="numericValue" select="10" />
<xsl:variable name="anotherValue" select="8" />
<xsl:variable name="vars" select="document('')/*/xsl:variable" />
<xsl:template match="/">
<xsl:variable name="referenceName" select="'numericValue'" />
<xsl:variable name="referenceValue" select="$vars[@name = $referenceName]/@select" />
Reference value: <xsl:value-of select="$referenceValue" />
</xsl:template>
</xsl:stylesheet>
这里需要注意的一个大限制是,这只适用于常量数值的变量
下面是一种使用常量字符串值模拟变量的方法:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:v="variables-node"
>
<v:variables>
<v:variable n="numericValue" value="10" />
<v:variable n="nonNumericValue" value="Hello World" />
</v:variables>
<xsl:variable name="vars" select="document('')//v:variables/v:variable" />
<xsl:template match="/">
<xsl:variable name="referenceName" select="'nonNumericValue'" />
<xsl:variable name="referenceValue" select="$vars[@n = $referenceName]/@value" />
<xsl:value-of select="concat('The variable with the name ', $referenceName, ' has the value ', $referenceValue)"/>
</xsl:template>
</xsl:stylesheet>
最后,用计算值模拟变量的方法:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common"
>
<xsl:variable name="varsRaw">
<var n="computedValue" value="{concat('2 + 4 is ', 2 + 4)}" />
<var n="computedNumber" value="{22 div 7}" />
</xsl:variable>
<xsl:variable name="vars" select="exslt:node-set($varsRaw)/var" />
<xsl:template match="/">
<xsl:variable name="referenceName" select="'computedValue'" />
<xsl:variable name="referenceValue" select="$vars[@n = $referenceName]/@value" />
<xsl:value-of select="concat('The variable with the name ', $referenceName, ' has the value ', $referenceValue)"/>
<xsl:value-of select="' '"/>
<xsl:variable name="referenceName2" select="'computedNumber'" />
<xsl:variable name="referenceValue2" select="$vars[@n = $referenceName2]/@value" />
<xsl:value-of select="concat('The variable with the name ', $referenceName2, ' has the value ', $referenceValue2)"/>
</xsl:template>
</xsl:stylesheet>
最后一种方法实际上可能是最正统的,但至少在XSLT 1.0节点集函数中需要依赖XSLT处理器。与大多数编程语言一样,XSLT变量名在运行时不可访问。该变量甚至可能在运行时不存在——优化器可以玩各种各样的把戏,比如在使用该变量的地方内联所有对该变量的引用
最好的方法是使用标准名称创建一个变量,并为其提供XML内容。与变量名不同,XML中的元素和属性名在运行时可以访问。顺便说一句,不要这样做:
<xsl:variable name="min"><xsl:value-of select="@minimum" /></xsl:variable>
当您可以这样做时:
<xsl:variable name="min" select="@minimum" />
它不仅冗长,而且效率低下——不需要复制数据和构建新树,这是一个非常昂贵的操作,而您只需要引用现有节点。当然,您是对的。它也更容易写,也更简短:这能回答你的问题吗?