Есть ли способ передать параметры / переменные в операторе XPath в .NET? - PullRequest
4 голосов
/ 19 июля 2011

Есть ли в C # XPath способ передать параметр, как вы можете сделать с помощью SQL select? Например:

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

Где он будет обрабатывать все побеги, расставлять кавычки и т. Д .?

1 Ответ

3 голосов
/ 19 июля 2011

.net XPath поддерживается для XPath 1.0. Однако существует простой способ добавить поддержку переменных, где вы можете сделать эквивалент вызова SetParameter () для вызова выбора SQL. Это также дает вам поддержку для определения ваших собственных функций, таких как match (). (Это из моего блога - Наведненные Врохи .)

Примечание. Мне не удалось найти способ добавить поддержку неравенств в датах. Если кто-нибудь знает способ добавить это, пожалуйста, дайте мне знать.

Вам необходимо создать собственный XsltContext. Для этого есть две хороших ссылки: регистрозависимый XPath в .NET и Добавление пользовательских функций в XPath .

Код в XPathCustomContext.cs хорошо документирован и прост, поэтому я не буду писать об этом здесь. Однако пара замечаний при его использовании:

  1. Измените значения Префикса и Пространства имен, чтобы вы не ходили по нашим Пространство имен.
  2. Вы помещаете переменную в XPath как $ name. Вы передаете это в XsltArgumentList и передать его вам в ResolveVariable как имя (без $).

И вот что важно - вы должны вызывать все вызовы Evaluate () и Select * (), используя XpathExpressions, как показано ниже. Если вы используете вызов, в котором вы непосредственно передаете XPath в качестве строки, вы получите исключение, в котором говорится, что вы используете неизвестную функцию. Это происходит, даже если вы передаете свой пользовательский контекст.

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);
...