Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to pass parameters/variables in an XPath statement in .NET?

Is there a way in the C# XPath to pass a parameter like you can do with a SQL select? For example:

XPathExpression expr = nav.Compile("/root/employee[@name = @p1]");
expr.SetParameter ("@p1", "Smith");

Where it would then handle all escapes, placing quotes around it, etc.?

like image 369
David Thielen Avatar asked Oct 10 '22 11:10

David Thielen


1 Answers

The .net XPath support is for XPath 1.0. However, there is an easy way to add support for variables where you can do the equivilent of a SetParameter() call on a SQL select call. This also gives you support for defining your own functions, like matches(). (This is from my blog - Windward Wrocks.)

Note: I was not able to find a way to add support for inequalities on dates. If anyone knows of a way to add this, please let me know.

You need to create a custom XsltContext. Two good references for this are Case-insensitive XPath in .NET and Adding Custom Functions to XPath.

The code in XPathCustomContext.cs is well documented and straightforward so I'm not going to write about it here. However a couple of notes when using it:

  1. Change the Prefix and Namespace values so you're not walking on our namespace.
  2. You put a variable in the XPath as $name. You pass it in XsltArgumentList and have it passed to you in ResolveVariable as name (no $).

And here's the biggie – you must call all Evaluate() and Select*() calls using XpathExpressions as shown below. If you use the call where you directly pass in the XPath as a string you will get an exception that says you are using an unknown function. This occurs even if you pass in your custom context.

private object SelectSingleNodeTyped(XPathNavigator nav, string select, XsltArgumentList parameters)
{
myContext.ArgList = parameters;
XPathExpression exp = nav.Compile(myXPathSelect);
exp.SetContext(myContext);
object obj = nav.Evaluate(exp);
like image 137
David Thielen Avatar answered Oct 14 '22 05:10

David Thielen