2010-12-11 24 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