Comment utiliser la fonction XPath dans une instance XPathExpression par programme?
-
03-07-2019 - |
Question
Mon programme actuel doit utiliser pour créer par programme une instance XPathExpression à appliquer à XmlDocument. Xpath doit utiliser certaines fonctions XPath telles que "ends-with". Cependant, je ne trouve pas le moyen d'utiliser " ends-with " dans XPath. Je
Il jette une exception comme ci-dessous
Exception non gérée: System.Xml.XPath.XPathException: Namespace Manager ou XsltC ontext nécessaire. Cette requête a un préfixe, variable ou fonction définie par l'utilisateur.
à MS.Internal.Xml.XPath.CompiledXpathExpr.get_QueryTree () à System.Xml.XPath.XPathNavigator.Evaluate (XPathExpression expr, contexte de l'opérateur XPathNodeIt)
à System.Xml.XPath.XPathNavigator.Evaluate (XPathExpression expr)
Le code est comme ceci:
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);
J'ai essayé de changer le code pour insérer XmlNamespaceManager lors de la compilation de l'expression, comme ci-dessous
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);
Il échoue lors de l'appel de XPathExpression.Compile:
Exception non gérée: System.Xml.XPath.XPathException: XsltContext est nécessaire pour cette requête à cause d'une fonction inconnue. à MS.Internal.Xml.XPath.CompiledXpathExpr.UndefinedXsltContext.ResolveFuncti on (préfixe de chaîne, nom de chaîne, XPathResultType [] ArgTypes) sur MS.Internal.Xml.XPath.FunctionQuery.SetXsltContext (XsltContext contexte) à MS.Internal.Xml.XPath.CompiledXpathExpr.SetContext (XmlNamespaceManager nsM anager) à System.Xml.XPath.XPathExpression.Compile (String xpath, IXmlNamespaceResolv er nsResolver)
Quelqu'un connaît le truc pour utiliser des fonctions XPath standard avec XPathExpression.Compile? Merci
La solution
La fonction < code> ends-with () n'est pas défini pour XPath 1.0 , mais uniquement pour XPath 2.0 et XQuery .
Vous utilisez .NET. NET à cette date n'implémente pas XPath 2.0 , XSLT 2.0 ou XQuery .
On peut facilement construire une expression XPath 1.0 dont l'évaluation produit le même résultat que la fonction end-with ()
:
$ str2 = sous-chaîne ($ str1, longueur de chaîne ($ str1) - longueur de chaîne ($ str2) +1)
produit le même résultat booléen ( true ()
ou false ()
) en tant que:
se termine par ($ str1, $ str2)
Dans votre cas concret, il vous suffit de substituer les expressions appropriées à $ str1
et $ str2
. Il s’agit donc de / myXml / data ??code>
et de "Monde"
.
L'expression XPath 1.0 à utiliser est donc équivalente à l'expression XPath 2.0 se termine par (/ myXml / data, "Monde")
est :
'World' =
substring(/myXml/data,
string-length(/myXml/data) - string-length('World') +1
)