Visual Studio 和 IE 之间的 XSL/JScript 行为差异
谁能告诉我为什么下面的 XSL 在 IE9 中可以顺利地转换下面的 XML,但在所有版本的 Visual Studio 中相同的转换都会失败?如果我在 IE 9 中打开 XML 文件,它会被转换并且输出符合预期,但如果我尝试在 Visual Studio 中对 XML 文件进行相同的转换(使用工具栏上的“Start XSLT”按钮),我会收到 JScriptException 操作
var node = root.nextNode();
修复似乎是更改 javascript 函数以执行以下
function test(root, attr)
{
root.MoveNext();
var node = root.Current;
return node.Select("breakfast" + attr);
}
:但是这会导致 IE 中的 XSLT 转换失败!我好像赢不了了!
XSL:
<!--<?xml version="1.0"?>-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:custom-scripts">
<msxsl:script language="JScript" implements-prefix="user">
<![CDATA[
function test(root, attr)
{
var node = root.nextNode();
return node.selectSingleNode("breakfast" + attr);
}
]]>
</msxsl:script>
<xsl:template match="/">
<HTML>
<BODY STYLE="font-family:Arial, helvetica, sans-serif; font-size:12pt;
background-color:#EEEEEE">
<xsl:value-of select="user:test(., '-menu')"/>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
目标 XML:
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="simple.xsl" ?>
<breakfast-menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>Two of our famous Belgian Waffles
with plenty of real maple syrup.</description>
<calories>650</calories>
</food>
<food>
<name>Homestyle Breakfast</name>
<price>$6.95</price>
<description>Two eggs, bacon or sausage, toast,
and our ever-popular hash browns.</description>
<calories>950</calories>
</food>
</breakfast-menu>
Can anyone tell me why the following XSL happily transforms the XML below in IE9, but the same transform fails under all versions of Visual Studio? If I open the XML file in IE 9, it gets transformed and the output is as expected, but if I attempt the same transform on the XML file in Visual Studio (using the 'Start XSLT' button on the toolbar) I get a JScriptException saying function expected on the line
var node = root.nextNode();
The fix seems to be to change the javascript function to do the following instead:
function test(root, attr)
{
root.MoveNext();
var node = root.Current;
return node.Select("breakfast" + attr);
}
But this then fails the XSLT transform in IE! I can't seem to win!
XSL:
<!--<?xml version="1.0"?>-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:custom-scripts">
<msxsl:script language="JScript" implements-prefix="user">
<![CDATA[
function test(root, attr)
{
var node = root.nextNode();
return node.selectSingleNode("breakfast" + attr);
}
]]>
</msxsl:script>
<xsl:template match="/">
<HTML>
<BODY STYLE="font-family:Arial, helvetica, sans-serif; font-size:12pt;
background-color:#EEEEEE">
<xsl:value-of select="user:test(., '-menu')"/>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
Target XML:
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="simple.xsl" ?>
<breakfast-menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>Two of our famous Belgian Waffles
with plenty of real maple syrup.</description>
<calories>650</calories>
</food>
<food>
<name>Homestyle Breakfast</name>
<price>$6.95</price>
<description>Two eggs, bacon or sausage, toast,
and our ever-popular hash browns.</description>
<calories>950</calories>
</food>
</breakfast-menu>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
IE 使用 MSXML 作为其 XSLT 处理器(我认为 IE 9 使用 MSXML 6),而 Visual Studio 使用 XslCompiledTransform。 MSXML 和 XslCompiledTransform 公开并使用的 API 差异很大,因此不要指望针对 MSXML API 编写的扩展函数代码能够与 XslCompiledTransform 和 .NET API 一起使用。请参阅http://msdn.microsoft.com/en-us/library/wxaw5z5e。 aspx 了解当您使用扩展函数时 XSLT/XPath 类型如何映射到 .NET 类型。在您的例子中,您传入一个节点集和一个来自 XSLT 的字符串,它们映射到 .NET 中的 XPathNodeIterator 和字符串。
这是重写 .NET 扩展函数的快速尝试:
[编辑]
糟糕,我错过了您已经自己找到了 .NET 代码并且只想知道如何针对两个 XSLT 处理器编写代码。那很难。你的目标平台是什么,你的目标是什么,你想为 IE 编写 XSLT 但用 VS 开发吗?或者您真的需要在 IE 和 .NET 平台上使用相同的样式表吗?
以下是为两种类型的处理器编写一个扩展函数的尝试:
Well IE uses MSXML as its XSLT processor (I think IE 9 uses MSXML 6) while Visual Studio uses XslCompiledTransform. The APIs exposed by and used with MSXML and XslCompiledTransform differ vastly so don't expect extension function code written against the MSXML API to work with XslCompiledTransform and the .NET API. See http://msdn.microsoft.com/en-us/library/wxaw5z5e.aspx on how XSLT/XPath types are mapped to .NET types when you use extension functions. In your case you pass in a node-set and a string from XSLT, that maps to an XPathNodeIterator and a String in .NET.
Here is a quick attempt to rewrite your extension function for .NET:
[edit]
Oops, I missed that you already found the .NET code yourself and only want to know how to write code against both XSLT processors. That is difficult. What is your target platform and your aim, do you want to write XSLT for IE but develop with VS? Or do you really need to use the same stylesheet within IE and on the .NET platform?
Here is an attempt to write one extension function for both type of processors:
您可能会发现 Visual Studio 中嵌入的浏览器不是 IE9。它很可能是 IE8 版本,或者可能是 IE7,具体取决于 Visual Studio 发布时哪个版本是稳定版本。
我对 XLST 的了解还不够多,无法解释它为什么不起作用,但这可能可以解释您所看到的行为差异。
You will probably find that the browser embedded into Visual Studio is not IE9. It is most likely to be a version of IE8, or maybe IE7 dependant on which was the stable version when your Visual Studio was released.
I don't really know enough about XLST to explain why it doesn't work, but this may explain the differences in the behaviour you are seeing.
我想知道 SO 上的这个答案是否相关? IE9 selectSingleNode 在测试版中缺失,如何解决这个问题在 JavaScript 中?
I wonder if this answer on SO will be relevant? IE9 selectSingleNode missing from beta, how to overcome this in JavaScript?