¿Cómo utilizar la función XPath en una instancia de XPathExpression mediante programación?

StackOverflow https://stackoverflow.com/questions/402211

  •  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

¿Fue útil?

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
             )
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top