Как сохранить текущий путь в xsl? - PullRequest
2 голосов
/ 12 декабря 2010

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

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

Ответы [ 3 ]

2 голосов
/ 12 декабря 2010

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

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

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

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

То, что вы хотите, может быть достигнуто более простым способом в XSLT с помощью инструкции <xsl:variable> :

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

Эта переменнаяна него можно ссылаться в любом месте области видимости как $theNode, и передавать в качестве параметра при применении или вызове шаблонов.

1 голос
/ 12 декабря 2010

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

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

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

0 голосов
/ 13 декабря 2010

Как отмечают @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
...