XSLT:XPath 上下文和 document()

发布于 2024-12-21 08:05:54 字数 1661 浏览 4 评论 0原文

我有一个像这样的 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 可以正确计算。但显然,这不是一个可以接受的解决方案。

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

I have an XSLT like this:

<?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>

In the second template, which matches nodes in the fooDocument.xml which is loaded with document(), I want to access nodes in the XML source the transformation is executed upon. This does not work with //someSourceElement, because apparently, XPath executes this path in the context of fooDocument.

A first workaround that comes to mind is this:

...
<!-- global variable -->
<xsl:variable name="root" select="/"/>

...
<!-- in the template -->
<xsl:variable name="valueFromSource" select="$root//someSourceElement"/>

...

But I cannot use this workaround, because actually, my variable is selected like this:

<xsl:variable name="valueFromSource" select="xalan:evaluate($someXPathString)"/>

$someXPathString is not crafted in the XSLT file, but loaded from fooDocument (and contains an absolute path like the one used above). Still, I need to somehow change the XPath context back to the XML source. A very hacky workaround I found is this:

<xsl:for-each select="$root[1]">
  <xsl:variable name="valueFromSource" select="xalan:evaluate($someXPathString)"/>
</xsl:for-each>

The (useless) for-each loop changes the context back to the main XML source, thus the XPath evaluates correctly. But obviously, this is not an acceptable solution.

Is there a way to do this right, or can someone suggest a better workaround?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧夏天 2024-12-28 08:05:54

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

Even if you think your attempt with a for-each select="$root" to change the context document is not acceptable this is the right approach. So use that, there is no other way.

或十年 2024-12-28 08:05:54

您是否考虑过使用一系列全局变量来完成构造 $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)"/>

Have you considered doing all the computation that constructs $someXPathString using a series of global variables?

<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)"/>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文