我创建了一个标准的XsltContext类,并按如下方式调用它:
XPathCustomContext context = new XPathCustomContext(new NameTable());
context.AddNamespace("windward", XPathCustomContext.Namespace);
XsltArgumentList varList = new XsltArgumentList();
varList.AddParam("stat-index", "", 0);
context.ArgList = varList;
XmlDocument doc = new XmlDocument();
doc.Load("c:\test\order.xml");
object xx = doc.CreateNavigator().Evaluate("/order[1]/customer[1]/num[@negone = $stat-index]", context);
当在.net 4.0下运行时,它运行良好。但在.NET 3.5(我们目前必须使用(下,我得到了:
System.Xml.XPath.XPathException was unhandled
Message=XsltContext is needed for this query because of an unknown function.
Source=System.Xml
StackTrace:
at MS.Internal.Xml.XPath.CompiledXpathExpr.UndefinedXsltContext.ResolveVariable(String prefix, String name)
at MS.Internal.Xml.XPath.VariableQuery.SetXsltContext(XsltContext context)
at MS.Internal.Xml.XPath.LogicalExpr.SetXsltContext(XsltContext context)
at MS.Internal.Xml.XPath.FilterQuery.SetXsltContext(XsltContext input)
at MS.Internal.Xml.XPath.CompiledXpathExpr.SetContext(XmlNamespaceManager nsManager)
at System.Xml.XPath.XPathExpression.Compile(String xpath, IXmlNamespaceResolver nsResolver)
at System.Xml.XPath.XPathNavigator.Evaluate(String xpath, IXmlNamespaceResolver resolver)
at CustomXpathFunctions.Program.Main(String[] args) in c:srcCustomXpathFunctionsProgram.cs:line 62
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
知道为什么吗?
示例代码位于http://www.windwardreports.com/temp/CustomXPathFunctionsBug.zip
感谢-dave
找到了一种方法。使用XPathExpression,如:
XPathNavigator nav = doc.CreateNavigator();
XPathExpression exp = nav.Compile("/order[1]/customer[1]/num[@negone = $stat]");
exp.SetContext(ctx);
object zzz = nav.Evaluate(exp);
至于原因,我的猜测是Evaluate(字符串,上下文(只在.NET3.5中将其用于命名空间,而XPathExpression则将其用于所有内容。但关键的一点是,这是有效的。
ps-请投票支持这个答案——这真的很难弄清楚。