Como usar a função XPath em uma instância de XPathExpression programação?
-
03-07-2019 - |
Pergunta
A minha necessidade programa atual para usar programaticamente criar uma instância de XPathExpression para aplicar a XmlDocument. O XPath precisa usar algumas funções XPath como "Termina com". No entanto, não consigo encontrar uma maneira de usar "fins-de-com" em XPath. I
É jogar exceção como abaixo
Exceção não tratada: System.Xml.XPath.XPathException: Namespace Manager ou XsltC ONTEXTO necessário. Esta consulta tem um prefixo, variável ou função definida pelo usuário.
em MS.Internal.Xml.XPath.CompiledXpathExpr.get_QueryTree () em System.Xml.XPath.XPathNavigator.Evaluate (XPathExpression expr, XPathNodeIt contexto Erator)
em System.Xml.XPath.XPathNavigator.Evaluate (XPathExpression expr)
O código é assim:
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);
Eu tentei mudar o código para inserir XmlNamespaceManager ao compilar a expressão, como abaixo
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);
Ele falha em XPathExpression.Compile invocação:
Exceção não tratada: System.Xml.XPath.XPathException: XsltContext é necessária para esta consulta por causa de uma função desconhecida. em MS.Internal.Xml.XPath.CompiledXpathExpr.UndefinedXsltContext.ResolveFuncti em (prefixo String, String nome, XPathResultType []) a ArgTypes MS.Internal.Xml.XPath.FunctionQuery.SetXsltContext (XsltContext contexto) a MS.Internal.Xml.XPath.CompiledXpathExpr.SetContext (XmlNamespaceManager NSM anager) a System.Xml.XPath.XPathExpression.Compile (String xpath, er IXmlNamespaceResolv nsResolver)
Alguém sabe o truque para usar off-the-shelf funções XPath com XPathExpression.Compile? Graças
Solução
A função ends-with()
não está definido para XPath 1.0 , mas somente para XPath 2.0 e XQuery .
Você está usando .NET. . NET nesta data não implementa ??strong> XPath 2.0 , XSLT 2.0 ou XQuery .
Pode-se construir facilmente uma expressão XPath 1.0, a avaliação de que produz o mesmo resultado que a função ends-with()
$str2 = substring($str1, string-length($str1)- string-length($str2) +1)
produz o mesmo resultado booleano (true()
ou false()
) como:
ends-with($str1, $str2)
No seu caso concreto, você só precisa substituir as expressões certas para $str1
e $str2
. Eles são, portanto, /myXml/data
e 'World'
.
ends-with(/myXml/data, 'World')
XPath 2.0 é
'World' =
substring(/myXml/data,
string-length(/myXml/data) - string-length('World') +1
)