如何使用 XPath 表达式“document('')”在 .NET XsltCompiledTransform 中?我应该吗?

发布于 2024-10-07 02:50:20 字数 548 浏览 4 评论 0原文

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

在我的 XSLT 中,我想使用非常类似于 :

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

(返回节点集)的 XPath。这在 Firefox 和 IE 中都非常有效,但它不适用于 XsltCompiledTransform - 它告诉我:

相对 URI 不支持此操作。

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

更一般地说,这种 XPath 查询是否常见?我是否陷入了一些我没有意识到的巨大 XSLT 陷阱?它会做出一些疯狂的事情,比如让网络浏览器变慢直至停止吗?

I'm currently working on a web site where we're sending down XML+XSLT to clients that support it, to save on bandwidth. However, if a client doesn't support it, we're doing the transform on the server side, and sending down the resulting HTML.

In my XSLT, I'd like to use an XPath very much like :

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

(to return a node-set). This works great in both Firefox and IE, but it doesn't work with the XsltCompiledTransform- it tells me:

This operation is not supported for a relative URI.

It looks like the error is occurring in XmlUrlResolver- I know I can pass a custom one of those in, but beyond that I'm not really not sure where I should be looking. Can anyone give me any hints as to how I might get this expression working? I'm happy to use some MSXSL extensions if needed- the code would only be seen on the server side, after all.

On a more general note- is it common to do this kind of XPath query? Am I falling into some giant XSLT trap I'm not aware of? Is it going to do something crazy like slow web browsers down to a halt?

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

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

发布评论

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

评论(3

時窥 2024-10-14 02:50:20

使用适当构造的 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 转换为常规节点集。在这里,只要 XSLT 处理器实现 EXSLT,就可以使用 exslt:node-set()。这仍然实现了相对较大程度的可移植性,因为许多 XSLT 处理器(包括 XslCompiledTransform)都支持 exslt:node-set()

Initiate the transform using an adequately constructed instance of XsltSettings, so that the document function is allowed.

Here is an example:

// 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());

Your other question:

On a more general note- is it common
to do this kind of XPath query? Am I
falling into some giant XSLT trap I'm
not aware of? Is it going to do
something crazy like slow web browsers
down to a halt?

The only pitfall is that this may cause the XSLT stylesheet to be re-parsed again, and this is a relatively slow operation.

More concerning is your use of the // abbreviation which is almost sure to cause performance problems.

It is much better to use this trick only for globall variables and then use this expression:

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

Finally, in case you are not concerned with losing portability between XSLT 1.0 processors, it is more efficient to use the xxx:node-set() implementation dependent extension function to convert the RTF of the variable to a regular node-set. Here, one could use exslt:node-set() provided the XSLT processor implements EXSLT. This still achieves a relatively big degree of portability, because many XSLT processors, including XslCompiledTransform support exslt:node-set().

﹏雨一样淡蓝的深情 2024-10-14 02:50:20

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

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

为:

msxsl:node-set($test)

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

I haven't managed to find a solution that allows me to use document(''), but since all I'm using it for is to get a variable to evaluate to a node-set, I'm adjusting the XML before processing on the server side, to change:

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

to:

msxsl:node-set($test)

Not exactly the most graceful solution, but it works for my purposes.

氛圍 2024-10-14 02:50:20

你尝试过使用吗

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

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

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

Have you tried using

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

? I.e. use a zero-length string as the argument to document(), instead of passing no arguments. According to the spec, document() must have at least one argument. I'm surprised Firefox and IE are lax about that. But that could explain why XsltCompiledTransform is unhappy.

On the other hand, if XsltCompiledTransform will not support a relative URI there, then '' may not work (it is considered a relative URI). It's possible that since it's compiling the transform, it's not convenient to provide access to a tree representation of the stylesheet. "An XSLT processor is not required to support any particular URI schemes. The documentation for an XSLT processor should specify which URI schemes the XSLT processor supports."

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