2010-12-11 36 views
2

我想存储当前节点的路径,以便我可以在XSLT中的表达式中重用它。可能吗?如何将当前路径存储在xsl中?

<!-- . into $path? -->  
<xsl:value-of select="$path" /> 
+0

问得好,+1。请参阅我的回答以获得解释和替代,更简单和实际的解决方案。 – 2010-12-12 03:51:28

回答

1

不,这是用vanilla XSLT 1.0不可能的。没有简单的方法来检索给定节点的XPath表达式字符串,并且绝对没有办法评估看起来像 XPath 的字符串,就好像它是 XPath。

有支持动态评估XPath表达式的扩展,但这些扩展与每个XSLT处理器都不兼容。

在任何情况下,如果您提供有关您实际尝试执行的更多细节,则可能有另一种方法来执行此操作。

2

您好,我想存储的 路径中的当前节点,所以我可以在XSLT在 重用它的表达式。可能吗?

可能的是,任何给定节点来构造的XPath表达式,计算时,选择究竟该节点。实际上,存在多个选择相同节点的XPath表达式。

请参阅this answer以获取构建此类XPath表达式的确切XSLT代码。

的问题是,此XPath表达式不能在相同的变换期间在XSLT 1.0或XSLT 2.0评价,除非EXSLT扩展函数DYN:评估被使用(并且很少XSLT 1.0处理器执行达因:评价() )。

你要能够以更简单的方式在XSLT使用<xsl:variable>指令实现什么:

<xsl:variable name="theNode" select="."/> 

这个变量可以在其范围内的任何地方引用为$theNode,可以作为参数传递应用或调用模板时。

0

由于@Dimitre和@Tomalak有一点出来,我不认为它在同一个转化一些价值,以获得代表给定节点的XPath表达式的字符串,然后选择节点“分析”这种字符串。我可以看到在执行这些操作在不同的转换有一些价值。

除此之外,这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes"/> 
    <xsl:template match="/"> 
     <xsl:for-each select=".|//node()|//@*"> 
      <xsl:variable name="vPath"> 
       <xsl:apply-templates select="." mode="getPath"/> 
      </xsl:variable> 
      <xsl:value-of select="concat($vPath,'&#xA;')"/> 
      <xsl:call-template name="select"> 
       <xsl:with-param name="pPath" select="$vPath"/> 
      </xsl:call-template> 
      <xsl:text>&#xA;</xsl:text> 
     </xsl:for-each> 
    </xsl:template> 
    <xsl:template match="/|node()|@*" mode="getPath" name="getPath"> 
     <xsl:apply-templates select="parent::*" mode="getPath"/> 
     <xsl:text>/</xsl:text> 
     <xsl:choose> 
      <xsl:when test="self::*"> 
       <xsl:value-of select="concat(name(),'[', 
              count(preceding-sibling::* 
                [name() = 
                 name(current())]) + 1, 
              ']')"/> 
      </xsl:when> 
      <xsl:when test="count(.|../@*)=count(../@*)"> 
       <xsl:value-of select="concat('@',name())"/> 
      </xsl:when> 
      <xsl:when test="self::text()"> 
       <xsl:value-of 
        select="concat('text()[', 
            count(preceding-sibling::text()) + 1, 
            ']')"/> 
      </xsl:when> 
      <xsl:when test="self::comment()"> 
       <xsl:value-of 
        select="concat('comment()[', 
            count(preceding-sibling::comment()) + 1, 
            ']')"/> 
      </xsl:when> 
      <xsl:when test="self::processing-instruction()"> 
       <xsl:value-of 
        select="concat('processing-instruction()[', 
            count(preceding-sibling:: 
              processing-instruction()) + 1, 
            ']')"/> 
      </xsl:when> 
     </xsl:choose> 
    </xsl:template> 
    <xsl:template name="select"> 
     <xsl:param name="pPath"/> 
     <xsl:param name="pContext" select="/"/> 
     <xsl:param name="pInstruction" select="'value-of'"/> 
     <xsl:variable name="vPosition" 
         select="number(
           substring-before(
            substring-after($pPath, 
                '['), 
            ']'))"/> 
     <xsl:variable name="vTest" 
         select="substring-before(
           substring-after($pPath, 
               '/'), 
           '[')"/> 
     <xsl:variable name="vPath" select="substring-after($pPath,']')"/> 
     <xsl:choose> 
      <xsl:when test="$vPath"> 
       <xsl:call-template name="select"> 
        <xsl:with-param name="pPath" select="$vPath"/> 
        <xsl:with-param name="pContext" 
            select="$pContext/*[name()=$vTest] 
                  [$vPosition]"/> 
        <xsl:with-param name="pInstruction" 
            select="$pInstruction"/> 
       </xsl:call-template> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:variable name="vContext" 
           select="$pContext/node() 
              [self::*[name()=$vTest]| 
              self::comment()[$vTest='comment()']| 
              self::text()[$vTest='text()']| 
              self::processing-instruction() 
               [$vTest = 
               'processing-instruction()']] 
              [$vPosition]| 
             $pContext[$pPath='/']| 
             $pContext/@*[name() = 
                substring($pPath,3)] 
                [not($vTest)]"/> 
       <xsl:choose> 
        <xsl:when test="$pInstruction='value-of'"> 
         <xsl:value-of select="$vContext"/> 
        </xsl:when> 
        <xsl:when test="$pInstruction='copy-of'"> 
         <xsl:copy-of select="$vContext"/> 
        </xsl:when> 
       </xsl:choose> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

有了这个输入:

<?somePI pseudoAttributes?> 
<root> 
    <!-- This is a comment --> 
    <node attribute="Value">text</node> 
</root> 

输出:

/ 
    text 
/processing-instruction()[1] 
pseudoAttributes 
/root[1] 
    text 
/root[1]/comment()[1] 
This is a comment 
/root[1]/node[1] 
text 
/root[1]/node[1]/@attribute 
Value 
/root[1]/node[1]/text()[1] 
text