2

我想存储当前节点的路径,以便可以在 XSLT 的表达式中重用它。是否可以?

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

3 回答 3

2

嗨,我想存储当前节点的路径,以便可以在 XSLT 的表达式中重用它。是否可以?

任何给定节点都可以构造一个 XPath 表达式,该表达式在计算时会准确选择该节点。事实上,存在不止一个选择同一个节点的 XPath 表达式。

有关构造此类 XPath 表达式的确切 XSLT 代码,请参阅此答案

问题是在 XSLT 1.0 或 XSLT 2.0 中的相同转换期间无法评估此 XPath 表达式,除非使用 EXSLT 扩展函数 dyn:evaluate(并且很少有 XSLT 1.0 处理器实现 dyn:evaluate() )。

您可以使用以下<xsl:variable>指令在 XSLT 中以更简单的方式实现您想要的:

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

此变量可以在其范围内的任何位置作为 引用$theNode并且可以在应用或调用模板时作为参数传递。

于 2010-12-12T03:50:03.640 回答
1

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

有一些扩展支持 XPath 表达式的动态求值,但这些扩展并不与每个 XSLT 处理器兼容。

无论如何,如果您提供有关您实际尝试做的事情的更多详细信息,则可能有另一种方法可以做到这一点。

于 2010-12-11T23:14:35.033 回答
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
于 2010-12-12T23:19:05.237 回答