请到 http://www.lostinet.com/files/XsltArgs.rar 下载例子源代码。

这个例子首先读取xml和xslt:
XmlDocument xmldoc=new XmlDocument();
xmldoc.Load(Server.MapPath(ResolveUrl("XmlFile1.xml")));
XslTransform xt=new XslTransform();
xt.Load(Server.MapPath(ResolveUrl("XsltFile1.xslt")));

然后创建XsltArgumentList:
XsltArgumentList arglist=new XsltArgumentList();

并且以XML名字空间"uri:myservice"的名义。把MyService的实例放到XsltArgumentList中:
arglist.AddExtensionObject("uri:myservice",new MyService());

最后进行转换:
xt.Transform(xmldoc,arglist,Response.Output,null);

这个代码很简单。关键是在Xslt里怎样用这个"uri:myservice"

首先在 stylesheet 里定义 xmlns:app="uri:myservice"
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:app="uri:myservice">
这样,就可以在表达式里直接应用uri:myservice了。

<xsl:value-of select="app:GetDateTimeString()" />
这里调用的是MyService.GetDateTimeString()

<xsl:value-of select="app:Add(@a,@b)" />
这里调用的是MyService.Add(int a,int b)

当然,除了常规的数据类型。你还可以传递XPathNodeIterator进去。这个与 xmlns:msxsl="urn:schemas-microsoft-com:xslt" 是一致的。

不过优点与缺点,主要就是编译期间的问题了。
(做这个是因为一个朋友说msxsl代码编译时找不到他写的类库,目前我不太清楚怎样控制xslt里的编译行为)
如果代码比较临时,并且可能根据不同的xslt来写不同的代码,那么推荐使用msxsl来写。
如果你本身有一些写好的东西了,或者不想同样的东西到处写,或者xslt根本就不是你负责的,就可以使用XsltArgumentList了。

关于msxsl请参考Saucer的文章:在.NET里用XSLT时怎么使用msxsl:script(http://blog.joycode.com/saucer/archive/2004/05/12/21273.aspx)

更新一:
<xsl:value-of select="app:Add(app:Sum(add/@a),app:Sum(add/@b))" />