Я хотел бы сохранить путь к текущему узлу, чтобы я мог повторно использовать его в выражении в XSLT. Является ли это возможным?Как сохранить текущий путь в xsl?
<!-- . into $path? -->
<xsl:value-of select="$path" />
Я хотел бы сохранить путь к текущему узлу, чтобы я мог повторно использовать его в выражении в XSLT. Является ли это возможным?Как сохранить текущий путь в xsl?
<!-- . into $path? -->
<xsl:value-of select="$path" />
Нет, это невозможно с использованием ванили XSLT 1.0. Нет простого способа получить строку выражения XPath для данного узла, и нет однозначного способа оценить строку, которая выглядит как XPath как будто это было XPath.
Существуют расширения, поддерживающие динамическую оценку выражений XPath, но они несовместимы с каждым процессором XSLT.
В любом случае, если вы предоставите более подробную информацию о том, что вы на самом деле пытаетесь сделать, может быть другой способ сделать это.
Привет, я хотел бы сохранить путь от текущего узла, так что я могу повторно использовать его в выражение в 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
, и может быть передан в качестве параметра при применении или вызове шаблонов.
Как @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,'
')"/>
<xsl:call-template name="select">
<xsl:with-param name="pPath" select="$vPath"/>
</xsl:call-template>
<xsl:text>
</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
Хороший вопрос, +1. См. Мой ответ для объяснения и альтернативного, более простого и реалистичного решения. –