我想使用一个变量作为XPath表达式的一部分,我的问题可能是msxsl节点集函数...不确定。
我的问题可能是msxsl节点集函数......不确定。但是不要让这个影响你的判断......读下去......。
我正在使用一个.NET函数来加载内容文件,该文件是通过定制的XML内容传递进来的。这个......我使用了一个.NET函数来加载内容文件,它是通过定制的XML内容传递进来的。@file
结果是一个XML文件。
在页面上定制的XML看起来像.XSL。
<control name="import" file="information.xml" node="r:container/r:group[@id='set01']/r:item[1]" />
XSL看起来像 。
<xsl:variable name="document">
<xsl:copy-of select="ext:getIncludedContent(@file)" />
</xsl:variable>
然后,我把它翻译成一个节点集,这样我就可以查询该文件
<xsl:variable name="preset-xml" select="msxsl:node-set($document)" />
我正在加载的源文件看起来像.NET Framework。
<container>
<group id="set01">
<item>value01</item>
<item>value02</item>
<item>value03</item>
</group>
<group id="set02">
<item>value04</item>
<item>value05</item>
</group>
</container>
它的工作原理直到这一点。我可以看到源文件被带入并输出为XML。
我的问题是,当我试图用从内容中输入的XPath表达式查询源文件时。
我试过用.NET Framework 2.0和.NET Framework 3.0查询源文件。
<xsl:value-of select="$preset-xml/@node" />
很明显,这是不工作的,因为它寻找@node作为加载在XML中的直接子节点。
我试过了:
<xsl:variable name="node" select="@node" />
<xsl:value-of select="$preset-xml/$node" />
但它不喜欢第二个变量。
我试过concat($preset-xml,'',$node),但结果还是把整个文档都画出来了。
目前我唯一能让它工作的方法就是在模板中写出完整的表达式。
<xsl:value-of select="$preset-xml/r:container/r:group[@id='set01']/r:item[1]" />
这样就能正确地将 value01
但那是一个硬编码的解决方案.我想开发一个可以从内容中进行操作的解决方案,以适应任何类型的导入内容,并在内容文件中声明参数。
p.s.我使用的是XSLT 1.0,因为技术管理员不会改变微软的解析器来支持以后版本的XSL,所以任何解决方案的编写都需要考虑到这一点。
XSLT中没有类似反射的功能。特别是MS XSLT引擎,在加载XSLT时编译XPath查询,而不是在应用到你的XML文档时。这样做是有原因的:它将代码(XSLT)和数据(输入XML)分开。
你试图通过混合代码和数据来实现什么;你确定你真的需要从输入的XML中执行一个任意的XPath表达式吗?例如,想一想,如果用户将输入的 @name
等于例如 //*
,然后你将向输出端发送整个输入的XML文档的内容,其中可能包含一些敏感数据。
如果你真的需要做你所描述的事情,你可以写你自己的 XSLT扩展对象,它将接受文档根和XPath查询,并将后者返回应用于前者。然后你就可以这样调用它了。
<xsl:value-of select="myExtensionNs:apply-xpath($preset-xml, @node)"/>
至于你最初的尝试 concat($preset-xml,'/',$node)
, concat
是字符串连接函数。你向它提供一些参数,它就会返回其字符串表示的连接。所以。concat($preset-xml,'/',$node)
将返回字符串值的 $preset-xml
,并与 /
,与$node的字符串值连在一起。如果你想写一个需要的XPath查询。concat('$preset-xml','/',$node)
似乎更符合逻辑(请注意引号);但是,仍然没有办法将结果字符串(如 $preset-xml/r:container/r:group[@id='set01']/r:item[1]
)到对应的XPath查询的值;它只能被发送到输出。
一个可能的技巧是调用一个参数化的 xsl:template
执行关键的选择比较部分,并将其输出评估为字符串。
我有一个类似的问题(计算一个任意属性值的所有节点),我是这样解决的(顺便说一句,我加载了一个二级xml文件的内容)。$sd = 'document($filename)'
所以我加载了一个二级xml文件的内容)。)
<xsl:template match="/">
<xsl:variable name="string_cntsuccess">
<xsl:for-each select="./Testcase">
<xsl:variable name="tcname" select="@location"/>
<xsl:for-each select="$sd//TestCase[@state='Passed']">
<xsl:call-template name="producedots">
<xsl:with-param name="name" select="$tcname"/>
</xsl:call-template>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="cntsuccess" select="string-length($string_cntsuccess)"/>
</xsl:template>
<xsl:template name="producedots">
<xsl:param name="name"/>
<xsl:variable name="ename" select="@name"/>
<xsl:if test="$name = $ename">
<xsl:text>.</xsl:text>
</xsl:if>
</xsl:template>