У меня есть XSLT, как это:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan">
<xsl:variable name="fooDocument" select="document('fooDocument.xml')"/>
<xsl:template match="/">
<xsl:apply-templates select="$fooDocument//*"/>
</xsl:template>
<xsl:template match="nodeInFooDocument">
<xsl:variable name="valueFromSource" select="//someSourceElement"/>
</xsl:template>
</xsl:transform>
Во втором шаблоне, который соответствует узлам в fooDocument.xml
, который загружается с document()
, я хочу получить доступ к узлам в источнике XML, над которым выполняется преобразование. Это не работает с //someSourceElement
, потому что, видимо, XPath выполняет этот путь в контексте fooDocument.
Первое обходное решение, которое приходит на ум, это:
...
<!-- global variable -->
<xsl:variable name="root" select="/"/>
...
<!-- in the template -->
<xsl:variable name="valueFromSource" select="$root//someSourceElement"/>
...
Но я не могу использовать этот обходной путь, потому что на самом деле моя переменная выбрана так:
<xsl:variable name="valueFromSource" select="xalan:evaluate($someXPathString)"/>
$someXPathString
создается не в XSLT-файле, а загружается из fooDocument (и содержит абсолютный путь, как тот, что использовался выше). Тем не менее, мне нужно каким-то образом изменить контекст XPath обратно на источник XML. Я нашел очень хакерский обходной путь:
<xsl:for-each select="$root[1]">
<xsl:variable name="valueFromSource" select="xalan:evaluate($someXPathString)"/>
</xsl:for-each>
(Бесполезный) цикл for-each
изменяет контекст обратно на основной источник XML, поэтому XPath оценивает правильно. Но очевидно, что это неприемлемое решение.
Есть ли способ сделать это правильно или кто-нибудь может предложить лучший обходной путь?