2

我目前正在一个网站上工作,我们正在向支持它的客户端发送 XML+XSLT,以节省带宽。但是,如果客户端不支持它,我们将在服务器端进行转换,并发送生成的 HTML。

在我的 XSLT 中,我非常喜欢使用 XPath:

document('')//xsl:variable[@name='test']

(返回一个节点集)。这在 Firefox 和 IE 中都很好用,但它不适用于 XsltCompiledTransform - 它告诉我:

相对 URI 不支持此操作。

看起来错误发生在 XmlUrlResolver 中 - 我知道我可以通过其中一个自定义,但除此之外我不确定我应该在哪里寻找。谁能给我任何关于如何让这个表达式起作用的提示?如果需要,我很乐意使用一些 MSXSL 扩展——毕竟,代码只能在服务器端看到。

在更一般的说明上——执行这种 XPath 查询是否常见?我是否陷入了一些我不知道的巨大 XSLT 陷阱?它会做一些疯狂的事情,比如缓慢的网络浏览器停止运行吗?

4

3 回答 3

1

使用适当构造的XsltSettings实例启动转换,以便允许使用文档功能

这是一个例子:

// Create the XsltSettings object with the document fn allowed.
XsltSettings settings = new XsltSettings(true,false);

// Create the XslCompiledTransform object and load the style sheet.
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("sort.xsl", settings, new XmlUrlResolver());

你的另一个问题

在更一般的说明上——执行这种 XPath 查询是否常见?我是否陷入了一些我不知道的巨大 XSLT 陷阱?它会做一些疯狂的事情,比如缓慢的网络浏览器停止运行吗?

唯一的缺陷是这可能会导致再次重新解析 XSLT 样式表,这是一个相对较慢的操作。

更令人担忧的是您使用的//缩写几乎肯定会导致性能问题。

最好只对全局变量使用这个技巧,然后使用这个表达式:

document('')/*/xsl:variable[@name='test']

最后,如果您不担心失去 XSLT 1.0 处理器之间的可移植性,使用xxx:node-set()实现相关的扩展函数将变量的 RTF 转换为常规节点集会更有效。在这里,exslt:node-set()只要 XSLT 处理器实现 EXSLT,就可以使用。这仍然实现了较大程度的可移植性,因为许多 XSLT 处理器,包括 XslCompiledTransform 支持exslt:node-set()

于 2010-12-10T06:21:06.140 回答
1

我还没有设法找到允许我使用 document('') 的解决方案,但由于我使用它的目的只是为了获取一个变量来评估节点集,所以我在处理之前调整了 XML在服务器端,更改:

document('')//xsl:variable[@name='test']

至:

msxsl:node-set($test)

不完全是最优雅的解决方案,但它适用于我的目的。

于 2010-12-10T14:26:39.713 回答
0

您是否尝试过使用

document('')//xsl:variable[@name='test']

? 即使用长度为零的字符串作为 的参数document(),而不是不传递任何参数。根据规范document()必须至少有一个参数。我很惊讶 Firefox 和 IE 对此松懈。但这可以解释为什么 XsltCompiledTransform 不高兴。

另一方面,如果 XsltCompiledTransform 不支持那里的相对 URI,则''可能不起作用(它被视为相对 URI)。有可能因为它正在编译转换,所以提供对样式表的树表示的访问并不方便。“XSLT 处理器不需要支持任何特定的 URI 方案。XSLT 处理器的文档应该指定 XSLT 处理器支持哪些 URI 方案。”

于 2010-12-10T05:37:11.580 回答