思归呓语

衣带渐宽终不悔,为伊消得人憔悴
随笔 - 396, 评论 - 2964, 引用 - 245

导航

工具

关于

标签

每月存档

广告



访客

 

今天在CSDN论坛上看到一个网友在请教关于msxsl:script的用法。感觉这问题也许有点意思,所以在下面简述一下。

在MSXML里,你在msxsl:script里可以使用Javascript和VBScript,参考

<msxsl:script> Element

但在.NET里,你只能使用那些.NET支持的语言,包括C#,VB.NET,JScript等。

譬如,我们想在XSLT里计算下面这个XML里people的和,

<root>
  <people>1</people>
  <people>2</people>
  <people>3</people>
  <people>4</people>
</root>


我们可以使用象这样的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />

<xsl:template match="/">
   sum:<xsl:value-of select="sum(root/people)"/>
</xsl:template>

</xsl:stylesheet>

在MSXML和浏览器里,我们也可以这么做,

<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:user="anything here">

<xsl:output method="text" />

<msxsl:script language="JavaScript" implements-prefix="user">
<![CDATA[
   function sum(nodelist)
   {
      var d = 0;
      var node = nodelist.nextNode();
      while (node != null)
      {
  d += parseInt(node.text);
  node = nodelist.nextNode();
      }

      return d;
   }
]]>
</msxsl:script>

<xsl:template match="/">
  sum:<xsl:value-of select="user:sum(root/people)"/>
</xsl:template>

</xsl:stylesheet>

但如果你在.NET下使用上述XSLT的话,你就会得到下列错误:

Unhandled Exception: System.Xml.Xsl.XsltException: Function 'user:sum()' has failed. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Microsoft.JScript.JScriptException: Function expected
Function expected
   at Microsoft.JScript.LateBinding.Call(Binder binder, Object[] arguments, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters, Boolean construct, Boolean brackets, VsaEngine engine)
   at Microsoft.JScript.LateBinding.Call(Object[] arguments, Boolean construct,Boolean brackets, VsaEngine engine)
   at Microsoft.Xslt.CompiledScripts.JScript.ScriptClass_1.sum(Object nodelist)
....

为什么?因为在MSXML里,nodelist这个nodeset参数是个IXMLDOMNodeList实例,其nextNode方法返回一个IXMLDOMNode实例。

而.NET则把这个nodeset参数映射到了System.Xml.XPath.XPathNodeIterator或其子类的实例(至于其他的Mapping,请参考XSLT Stylesheet Scripting using <msxsl:script>或后面提到的Aaron Skonnard的文章)。实际上,如果你运行上述转换的话,你看到的是XPathQueryIterator类。但不管如何,在.NET下,你只能使用.NET下的类,而不能使用那些跟MSXML有关的类/方法,譬如

<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:user="anything here"
>

<xsl:output method="text" />

<msxsl:script language="Javascript" implements-prefix="user">
function getType(nxpni)
{
  return nxpni.GetType().Name;
}

function sum(nxpni)
{
  var d = 0;
  while (nxpni.MoveNext())
 d += Convert.ToInt32(nxpni.Current.Value);

   return d;
}
</msxsl:script>


<xsl:template match="/">
   type:<xsl:value-of select="user:getType(.)"/>
   sum:<xsl:value-of select="user:sum(root/people)"/>
</xsl:template>

</xsl:stylesheet>

当然你也可使用C#

<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:user="anything here"
>

<xsl:output method="text" />

<msxsl:script language="C#" implements-prefix="user">
string getType(XPathNodeIterator nxpni)
{
  return nxpni.GetType().Name;
}

int sum(XPathNodeIterator nxpni)
{
  int d = 0;
  while (nxpni.MoveNext())
 d += Convert.ToInt32(nxpni.Current.Value);

   return d;
}
</msxsl:script>


<xsl:template match="/">
   type:<xsl:value-of select="user:getType(.)"/>
   sum:<xsl:value-of select="user:sum(root/people)"/>
</xsl:template>

</xsl:stylesheet>

Aaron Skonnard在MSDN杂志上的专栏《The XML Files 》里对此曾有专述

Extending XSLT with JScript, C#, and Visual Basic .NET

如果你想在XSLT里使用.NET下的扩展函数的话,参考微软Dare Obasanjo在MSDN上的Extreme XML专栏

EXSLT Meets XPath

相关文章

打印 | 张贴于 2004-05-12 05:06:00 | Tag:暂无标签

留言反馈

#re: 在.NET里用XSLT时怎么使用msxsl:script 编辑
在 .NET 里格式化的时候
jscript 和 javascript 用的是 jscript 7 也就 jscript.net
至于 vbscript 没有测试过 可能是用 visualbasic.net

另外 vabug 兄
首先你要明白 解析你的 script 是宿主是 xsl
而不是浏览器 当然不会有 document 对象



2006-06-22 22:21:00 | [匿名用户:slightboy]
#re: 在.NET里用XSLT时怎么使用msxsl:script 编辑
# 回复: 在.NET里用XSLT时怎么使用msxsl:script 2004-5-12 19:57 drason
有一点需要更正:
msxsl:script不能使用VBScript
只能使用JScript和javascript



谁说不能使用VBScript.
2006-05-12 22:16:00 | [匿名用户:rabit]
#re: 在.NET里用XSLT时怎么使用msxsl:script 编辑
# 回复: 在.NET里用XSLT时怎么使用msxsl:script 2004-5-12 19:57 drason
有一点需要更正:
msxsl:script不能使用VBScript
只能使用JScript和javascript



谁说不能使用VBScript.

当然可以用.
2006-05-12 22:16:00 | [匿名用户:rabit]
#re: 在.NET里用XSLT时怎么使用msxsl:script 编辑
# 回复: 在.NET里用XSLT时怎么使用msxsl:script 2004-5-12 19:57 drason
有一点需要更正:
msxsl:script不能使用VBScript
只能使用JScript和javascript



谁说不能使用VBScript.

当然可以用.
2006-05-12 22:16:00 | [匿名用户:rabit]
#re: 在.NET里用XSLT时怎么使用msxsl:script 编辑
# 回复: 在.NET里用XSLT时怎么使用msxsl:script 2004-5-12 19:57 drason
有一点需要更正:
msxsl:script不能使用VBScript
只能使用JScript和javascript



谁说不能使用VBScript.

当然可以用.
2006-05-12 22:16:00 | [匿名用户:rabit]
#re: 在.NET里用XSLT时怎么使用msxsl:script 编辑
# 回复: 在.NET里用XSLT时怎么使用msxsl:script 2004-5-12 19:57 drason
有一点需要更正:
msxsl:script不能使用VBScript
只能使用JScript和javascript



谁说不能使用VBScript.

当然可以用.
2006-05-12 22:16:00 | [匿名用户:rabit]
#re: 在.NET里用XSLT时怎么使用msxsl:script 编辑
vabug 写的这个
<xsl:template match="/">
HtmlCode:
<script LANGUAGE="JavaScript1.2">
document.write('<xsl:value-of select="code"/>');
</script>
</xsl:template>

最后到底能不能工作啊?因为我也想用document这个对象输出字符串。由于这个字符串里可能含有html的标记,但是又是动态的。如果直接向浏览器输出,那么得到的是包含<>的文本。楼主有没有什么想法啊
2005-09-06 21:54:00 | [匿名用户:busbby]
#re: 在.NET里用XSLT时怎么使用msxsl:script 编辑
思归:
   你好,我在XSL中使用了document('')引用了自己,在.net中转换的时候不能解释有document('')的语句,应该怎么定义XmlResolver呀?
2005-05-10 11:59:00 | [匿名用户:dagco]
#回复: 在.NET里用XSLT时怎么使用msxsl:script 编辑
you should read my post carefully, when I said Javascript/VBScript, I meant in the MSXML environment
2004-05-14 02:01:00 | [匿名用户:saucer]
#回复: 在.NET里用XSLT时怎么使用msxsl:script 编辑
个人不喜欢使用msxsl:script 这个扩展。影响效率。而且,Standard Xsl 其实也能做很多事情的。
我记得以前W3C 在制定XSLT 标准的时候,对是不是引入xsl:script 好像很有些争议,以前的XSL 草案里是有script的,到XSLT 1.0里就把它给干掉了
2004-05-13 04:10:00 | [匿名用户:Zee]
#回复: 在.NET里用XSLT时怎么使用msxsl:script 编辑
有一点需要更正:
msxsl:script不能使用VBScript
只能使用JScript和javascript
2004-05-12 19:57:00 | [匿名用户:drason]
#回复: 在.NET里用XSLT时怎么使用msxsl:script 编辑
多谢思归
解决了长久以来的疑问~
2004-05-12 10:50:00 | [匿名用户:Sunmast]
#回复: 在.NET里用XSLT时怎么使用msxsl:script 编辑
天啊。不说不知道。
要对XSLT重新定位一下了。。
要认真考虑一下XSLT更多的事情
:)
2004-05-12 10:19:00 | [匿名用户:Lostinet]
对不起,目前本随笔不允许发表新评论.

Powered by: Joycode MVC Blogger System