任何人都可以告诉我为什么以下XSL在IE9中愉快地转换下面的XML,但在所有版本的Visual Studio中相同的转换失败了吗?如果我在IE 9中打开XML文件,它会被转换并且输出是预期的,但如果我在Visual Studio中对XML文件尝试相同的转换(使用工具栏上的“启动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>
答案 0 :(得分:2)
IE使用MSXML作为其XSLT处理器(我认为IE 9使用MSXML 6),而Visual Studio使用XslCompiledTransform。 MSXML和XslCompiledTransform公开并使用的API差别很大,因此不要指望针对MSXML API编写的扩展函数代码可以与XslCompiledTransform和.NET API一起使用。有关使用扩展函数时XSLT / XPath类型如何映射到.NET类型的信息,请参阅http://msdn.microsoft.com/en-us/library/wxaw5z5e.aspx。在您的情况下,您传入一个节点集和一个来自XSLT的字符串,它映射到XPathNodeIterator和.NET中的String。 以下是重写.NET扩展函数的快速尝试:
<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(nodeIterator, string)
{
nodeIterator.MoveNext();
return nodeIterator.Current.SelectSingleNode("breakfast" + string);
}
]]>
</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>
[编辑] 糟糕,我错过了你自己已经找到了.NET代码,并且只想知道如何针对两个XSLT处理器编写代码。这很难。你的目标平台和目标是什么,你想为IE编写XSLT但是用VS开发吗?或者你真的需要在IE和.NET平台上使用相同的样式表吗?
这是尝试为两种类型的处理器编写一个扩展函数:
<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(nodeSet, string)
{
if (typeof nodeSet.nextNode !== 'undefined') {
var node = nodeSet.nextNode();
return node.selectSingleNode('breakfast' + string);
}
else if (typeof nodeSet.MoveNext !== 'undefined') {
nodeSet.MoveNext();
return nodeSet.Current.SelectSingleNode("breakfast" + string);
}
}
]]>
</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>
答案 1 :(得分:1)
您可能会发现Visual Studio中嵌入的浏览器不是IE9。它最有可能是IE8的一个版本,或者IE7依赖于Visual Studio发布时的稳定版本。
我对XLST的了解不足以解释为什么它不起作用,但这可以解释你所看到的行为的差异。
答案 2 :(得分:1)