XSLT: XPath上下文和文档()



我有一个这样的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>

在第二个模板中,它匹配加载了document()fooDocument.xml中的节点,我想访问执行转换的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计算正确。但很明显,这不是一个可以接受的解决方案。

是否有办法做到这一点正确,或者有人可以建议一个更好的解决方案?

即使您认为使用for-each select="$root"更改上下文文档的尝试是不可接受的,这也是正确的方法。就用这个吧,没有别的办法了

您是否考虑过使用一系列全局变量构建$someXPathString的所有计算?

<xsl:variable name="fooDocument" select="document('fooDocument.xml')"/>
<xsl:variable name="temp1"
  .. some computation using fooDocument ..
</xsl:variable>
<xsl:variable name="temp2"
  .. some computation using temp1 ..
</xsl:variable>
<xsl:variable name="someXPathString"
  .. some computation using temp2 ..
</xsl:variable>
<xsl:variable name="root" select="xalan:evaluate($someXPathString)"/>

最新更新