Как программно использовать функцию XPath в экземпляре XPathExpression?
-
03-07-2019 - |
Вопрос
Моей текущей программе необходимо программно создать экземпляр XPathExpression для применения к XmlDocument.XPath должен использовать некоторые функции XPath, такие как «заканчивается».Однако я не могу найти способ использовать «заканчивается» в XPath.я
Это вызывает исключение, как показано ниже
Необработанное исключение:System.Xml.XPath.XPathException:Требуется менеджер по именам или XSLTC Ontext.Этот запрос имеет префикс, переменную или определенную пользовательскую функцию.
В Ms.Internal.xml.xpath.compiledxpathexpr.get_querytree () At System.xml.xpath.xpathnavigator.evaluate (xpathexpression expr, контекст xpathnodeit erator)
at system.xml.xpath.xpathnavigator.evaluate (xpathexpression expr)
Код такой:
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 необходим для этого запроса из -за неизвестной функции.at ms.internal.xml.xpath.compiledxpathexpr.undefinedxsltcontext.resolvefuncti on (string prefix, string name, xpathresulttype [] argtypes) на ms.internal.xml.xpath.functionquery.setxslcontext (xsltcontextextext. Xpath.compiledxpathexpr.setcontext (xmlnamespacemanager nsm anager) в system.xml.xpath.xpathexpression.compile (String xpath, ixmlnamespaceresolv er nsresolver)
Кто-нибудь знает, как использовать готовые функции XPath с XPathExpression.Compile?Спасибо
Решение
Функция 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
)