2011-05-23 40 views
1

谁能告诉我为什么下面的XSL在IE9中愉快地转换下面的XML,但是在所有版本的Visual Studio下,相同的转换都失败了?如果我在IE 9中打开XML文件,它会被转换并且输出如预期的那样,但是如果我在Visual Studio中对XML文件进行相同的转换(使用工具栏上的“启动XSLT”按钮),我会得到一个JScriptException话说功能有望上线Visual Studio和IE之间行为的XSL/JScript差异

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> 

回答

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> 
+0

谢谢 - 我想你已经找到了答案。我不打算为两者开发,我想这只是一个工作流程问题 - 我在部署在IE上之前在Visual Studio中进行了调试,所以这给我带来了一些麻烦。 – 2011-05-23 11:33:42

1

你可能会发现嵌入到Visual Studio中的浏览器不是IE9。它最有可能是IE8的一个版本,或者IE7依赖于Visual Studio发布时的稳定版本。

我对XLST解释不清楚为什么它不起作用,但这可能会解释您看到的行为差异。