第一次使用msxsl:script

开始使用XSLT来解析XML文件。
刚开始,我沿用了XMLDOM的思维,企图通过给Script的函数传入XPath来解析XML文件。但是一直报告“Microsoft.JScript.JScriptException: Function expected
”的错误。例如下面的代码:

<Root>
    
<Members>
        
<Member id='1' name='Test1'/>
        
<Member id='2' name='Test2'/>
    
</Members>
    
<Logs>
        
<Log id='1' Date='2004-07-27' member='1'>Test Log</Log>
        
<Log id='1' Date='2004-07-28' member='2'>Test Log by Test2</Log>
    
</Logs>
</Root>

我想根据传入的Log节点获取Log,并同时获取提交的member的name,于是我写了如下的代码:
<xsl:for-each select="Logs/Log">    <xsl:value-of select="JS:GetMemberName(/Members, @member)"/>
</xsl:for-each>

其中的JScript是:
<msxsl:script language="JScript" implements-prefix="UE">
function GetMemberName(members, requestID)
{
    
var memberList = members.selectNodes('Member');
    
}
</msxsl:script>

但是,运行之后却报出“Microsoft.JScript.JScriptException: Function expected
”的错误。很显然,我使用的selectNodes这个函数不能被识辨。
折腾了很久,我突然想到,我获得的报错信息是来之.net runtime的,也就是说,也许我可以使用GetType()方法得到传入的members的类型,于是我把代码改成了下面的代码:
<msxsl:script language="JScript" implements-prefix="UE">
function GetMemberName(members, requestID)
{
    
return members.GetType().ToString();    
}
</msxsl:script>

果然,返回的类型是:
XPathNodeIterator
查找这个类的相关信息,发现这个类有如下几个方法:
bool MoveNext()
XPathNavigator Current
int Count
int CurrentPosition
通过MoveNext可以获取其中的元素,而Current可以得到XPathNavigator对象。这一下简单了,通过XPathNavigator可以获得Member了。
于是,我把代码改成了如下的代码:
<msxsl:script language="JScript" implements-prefix="UE">
function GetMemberName(members, requestID)
{
    
while(members.MoveNext())
    {
          
var innermember = members.Current.SelectChildren("Member""");
          
while(innermember.MoveNext())
          {
               getUserID 
= innermember.Current.GetAttribute("id""");
              
if(getUserID == requestID)
                   
return innermember.Current.GetAttribute("name""");
          }
     }
        return "";    
}
</msxsl:script>

但是奇怪的是,我依然无法获取正确的名字,每次返回都是空字符。跟踪发现if(getUserID == requestID)没有正确运行。这时,我想到,可能传入的requestID同样是XPathNodeIterator对象,于是我把代码再修改了一下:
<msxsl:script language="JScript" implements-prefix="UE">
function GetMemberName(members, requestID)
{
    
var submitUserId = 0;
    
if(requestID.MoveNext())
    {
        submitUserId 
= requestID.Current.ToString();
    }
    
while(members.MoveNext())
    {
           
var innermember = members.Current.SelectChildren("Member""");
           
while(innermember.MoveNext())
          {
               getUserID 
= innermember.Current.GetAttribute("id""");
               
if(getUserID == submitUserId)
               
return innermember.Current.GetAttribute("name""");
          }
     }
        
return "";    
}
</msxsl:script>

我增加了一个步骤,即从XPathNavigator中获取值,果然,运行成功了。
看来,在.net中,传入函数的节点被映射成了XPathNavigator对象,而且无论传入的是节点还是节点的属性。
原文地址:https://www.cnblogs.com/iaxes/p/27964.html