¿Cómo utilizar la función XPath en una instancia de XPathExpression mediante programación?
-
03-07-2019 - |
Pregunta
Mi programa actual necesita usar programáticamente crear una instancia de XPathExpression para aplicar a XmlDocument. El xpath necesita usar algunas funciones XPath como "termina con". Sin embargo, no puedo encontrar una manera de usar " termina con " en XPath. Yo
Lanzar excepción como abajo
Excepción no controlada: System.Xml.XPath.XPathException: Administrador de espacio de nombres o XsltC ontext necesario. Esta consulta tiene un prefijo, variable, o función definida por el usuario.
a MS.Internal.Xml.XPath.CompiledXpathExpr.get_QueryTree () a System.Xml.XPath.XPathNavigator.Evaluate (XPathExpression expr, XPathNodeIt erator context)
a System.Xml.XPath.XPathNavigator.Evaluate (XPathExpression expr)
El código es así:
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);
Intenté cambiar el código para insertar XmlNamespaceManager al compilar la expresión, como a continuación
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);
Falla en XPathExpression. Invocación de compilación:
Excepción no controlada: System.Xml.XPath.XPathException: XsltContext es necesario para esta consulta debido a una función desconocida. a MS.Internal.Xml.XPath.CompiledXpathExpr.UndefinedXsltContext.ResolveFuncti en (prefijo de cadena, nombre de cadena, XPathResultType [] ArgTypes) en MS.Internal.Xml.XPath.FunctionQuery.SetXsltContext (XsltContext contexto) en MS.Internal.Xml.XPath.CompiledXpathExpr.SetContext (XmlNamespaceManager nsM anager) en System.Xml.XPath.XPathExpression.Compile (String xpath, IXmlNamespaceResolv er nsResolver)
¿Alguien sabe el truco para usar las funciones XPath estándar con XPathExpression.Compile? Gracias
Solución
La función < code> termina con () no está definido para XPath 1.0 pero solo para XPath 2.0 y XQuery .
Estás utilizando .NET. . NET en esta fecha no se implementa XPath 2.0 , XSLT 2.0 o XQuery .
Se puede construir fácilmente una expresión XPath 1.0, cuya evaluación produce el mismo resultado que la función ends-with()
:
$ str2 = substring ($ str1, string-length ($ str1) - string-length ($ str2) +1)
produce el mismo resultado booleano ( true ()
o false ()
) que:
termina con ($ str1, $ str2)
En su caso concreto, solo necesita sustituir las expresiones correctas por $str1
y $str2
. En consecuencia, son /myXml/data
y 'World'
.
Entonces, la expresión XPath 1.0 a usar, que es equivalente a la expresión XPath 2.0 termina con (/ myXml / data, 'World')
es :
'World' =
substring(/myXml/data,
string-length(/myXml/data) - string-length('World') +1
)