2012-05-17 1 views
3

XPath Мне нужно, чтобы получить XPath текущего узла, для которого я написал функцию XslПолучить текущие узлы

<func:function name="fn:getXpath"> 
    <xsl:variable name="xpath"> 
     <xsl:for-each select="ancestor-or-self::*"> 
      <xsl:value-of select="concat($xpath, name())" /> 
      <xsl:if test="not(position()=last())"> 
       <xsl:value-of select="concat('/', $xpath)" /> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:variable> 
    <func:result select="$xpath" /> 
</func:function> 

Но когда я запускаю это, я получаю следующее сообщение об ошибке

file:///D:/test.xsl; Line #165; Column #63; Variable accessed before it is bound! 
file:///D:/test.xsl; Line #165; Column #63; java.lang.NullPointerException 

Я использую xalan 2.7.0. Пожалуйста помоги.

+0

После устранения очевидной ошибки получившееся выражение, как правило, будет правильным. Зачем? Потому что в общем случае это выражение XPath выбирает множество элементов, а не только одно. –

+0

Вы столкнетесь с проблемами в любом месте, где есть два родных брата с тем же именем, '' будет давать вам идентичное выражение для обоих узлов ''. Вы должны найти способ добавления '[1]', '[2]' и т. Д., Возможно, используя функцию 'position()' или 'before-sibling'. – Flynn1179

ответ

2

Вы используете переменную $xpath внутри определения самого переменный:

<func:function name="fn:getXpath"> 
    <xsl:variable name="xpath"> 
     <xsl:for-each select="ancestor-or-self::*"> 
      <xsl:value-of select="concat($xpath, name())" /> <------- 
      <xsl:if test="not(position()=last())"> 
       <xsl:value-of select="concat('/', $xpath)" /> <------- 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:variable> 
    <func:result select="$xpath" /> 
</func:function> 

переменные не известно в этой точке.

6

В вашем примере вы пытаетесь использовать переменную в самом определении, что недопустимо.

Понадобилось попытаться изменить значение существующего значения. Однако XSLT является функциональным языком, и в результате переменные неизменяемы. Это означает, что вы не можете изменить значение после определения.

В этом случае вам не нужно быть таким сложным. Вы можете просто удалить ссылку на переменную, и вы получите нужный результат.

<func:function name="fn:getXpath"> 
    <xsl:variable name="xpath"> 
     <xsl:for-each select="ancestor-or-self::*"> 
     <xsl:value-of select="name()"/> 
     <xsl:if test="not(position()=last())"> 
      <xsl:value-of select="'/'"/> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:variable> 
    <func:result select="$xpath" /> 
</func:function> 
+1

В идеале этот ответ должен был быть отмечен принятым! :) +1 –