2010-12-11 4 views
2

Я хотел бы сохранить путь к текущему узлу, чтобы я мог повторно использовать его в выражении в XSLT. Является ли это возможным?Как сохранить текущий путь в xsl?

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

Хороший вопрос, +1. См. Мой ответ для объяснения и альтернативного, более простого и реалистичного решения. –

ответ

1

Нет, это невозможно с использованием ванили XSLT 1.0. Нет простого способа получить строку выражения XPath для данного узла, и нет однозначного способа оценить строку, которая выглядит как XPath как будто это было XPath.

Существуют расширения, поддерживающие динамическую оценку выражений XPath, но они несовместимы с каждым процессором XSLT.

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

2

Привет, я хотел бы сохранить путь от текущего узла, так что я могу повторно использовать его в выражение в XSLT. Является ли это возможным?

Вполне возможно, для любого заданного узла построить выражение XPath, что, при оценке, выбирает именно этот узел. Фактически существует более одного выражения XPath, которое выбирает один и тот же узел.

См. this answer для точного кода XSLT, который создает такое выражение XPath.

Проблема заключается в том, что это выражение XPath, не может быть оценен в течение того же преобразования в XSLT 1.0 или XSLT 2.0, если только EXSLT функции расширения динам: не оценивать используется (и очень немногие XSLT 1.0 процессоров реализовать DYN: оценки()).

То, что вы хотите, может быть достигнуто более простым способом в 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 
Смежные вопросы