使用变量作为XPath选择的一部分。

问题描述 投票:1回答:2

我想使用一个变量作为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,所以任何解决方案的编写都需要考虑到这一点。

variables xslt xpath
2个回答
0
投票

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查询的值;它只能被发送到输出。


0
投票

一个可能的技巧是调用一个参数化的 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>
© www.soinside.com 2019 - 2024. All rights reserved.