Как программно использовать функцию XPath в экземпляре XPathExpression? - PullRequest
9 голосов
/ 31 декабря 2008

Моя текущая программа должна использовать программно создать экземпляр XPathExpression для применения к XmlDocument. Xpath должен использовать некоторые функции XPath, такие как «заканчивается». Тем не менее, я не могу найти способ использовать «конец» в XPath. I

Выдает исключение, как показано ниже

Необработанное исключение: System.Xml.XPath.XPathException: Диспетчер пространства имен или XsltC ontext необходимо. Этот запрос имеет префикс, переменная или пользовательская функция.
в MS.Internal.Xml.XPath.CompiledXpathExpr.get_QueryTree () в System.Xml.XPath.XPathNavigator.Evaluate (XPathExpression expr, контекст XPathNodeIt)
в System.Xml.XPath.XPathNavigator.Evaluate (XPathExpression выраж)

Код такой:

    XmlDocument xdoc = new XmlDocument();
    xdoc.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8"" ?>
                        <myXml xmlns=""http://MyNamespace"" xmlns:fn=""http://www.w3.org/2005/xpath-functions""> 
                        <data>Hello World</data>
                    </myXml>");
    XPathNavigator navigator = xdoc.CreateNavigator();

    XPathExpression xpr;
    xpr = XPathExpression.Compile("fn:ends-with(/myXml/data, 'World')");

    object result = navigator.Evaluate(xpr);
    Console.WriteLine(result);

Я пытался изменить код для вставки XmlNamespaceManager при компиляции выражения, как показано ниже

    XmlDocument xdoc = new XmlDocument();
    xdoc.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8"" ?>
                        <myXml xmlns=""http://MyNamespace"" xmlns:fn=""http://www.w3.org/2005/xpath-functions""> 
                        <data>Hello World</data>
                    </myXml>");
    XPathNavigator navigator = xdoc.CreateNavigator();
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(xdoc.NameTable);
    nsmgr.AddNamespace("fn", "http://www.w3.org/2005/xpath-functions");

    XPathExpression xpr;
    xpr = XPathExpression.Compile("fn:ends-with(/myXml/data, 'World')", nsmgr);

    object result = navigator.Evaluate(xpr);
    Console.WriteLine(result);

Сбой при вызове XPathExpression.Compile:

Необработанное исключение: System.Xml.XPath.XPathException: XsltContext необходим для этого запроса из-за неизвестной функции. в MS.Internal.Xml.XPath.CompiledXpathExpr.UndefinedXsltContext.ResolveFuncti вкл (префикс строки, имя строки, XPathResultType [] ArgTypes) в MS.Internal.Xml.XPath.FunctionQuery.SetXsltContext (XsltContext контекст) в MS.Internal.Xml.XPath.CompiledXpathExpr.SetContext (XmlNamespaceManager nsM anager) в System.Xml.XPath.XPathExpression.Compile (String xpath, IXmlNamespaceResolv er nsResolver)

Кто-нибудь знает хитрость использования готовых функций XPath с XPathExpression.Compile? Спасибо

1 Ответ

33 голосов
/ 31 декабря 2008

Функция ends-with() не определена для XPath 1.0 , но только для XPath 2.0 и XQuery .

Вы используете .NET. . NET на эту дату не реализует XPath 2.0 , XSLT 2.0 или XQuery .

Можно легко построить выражение XPath 1.0, вычисление которого дает тот же результат, что и функция ends-with():

$str2 = substring($str1, string-length($str1)- string-length($str2) +1)

выдает тот же логический результат (true() или false()), что и:

ends-with($str1, $str2)

В вашем конкретном случае вам просто нужно заменить правильные выражения на $str1 и $str2. Это соответственно /myXml/data и 'World'.

Итак, используемое выражение XPath 1.0, эквивалентное выражению XPath 2.0 ends-with(/myXml/data, 'World'), равно :

'World' = 
   substring(/myXml/data,
             string-length(/myXml/data) - string-length('World') +1
             )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...