您的位置:首页 > 其它

在.NET里用XSLT时怎么使用msxsl:script

2006-08-10 15:41 447 查看
在这里http://www.netgrid.cn/blog/showlog.asp?log_id=459看到这篇文章的

在博客堂上看到这篇文章。不过,要更好地在windows平台下进行xml有关的开发,还是要好好的抗议看msxml3/4的帮助文档。

在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="' target=_blank>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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: