2008-12-31 8 views
9

Mi programa actual necesita usar programáticamente crear una instancia de XPathExpression para aplicar a XmlDocument. El xpath necesita usar algunas funciones XPath como "ends-with". Sin embargo, no puedo encontrar una forma de usar "ends-with" en XPath. Me¿Cómo se usa la función XPath en una instancia de XPathExpression mediante programación?

Se excepción tiro, como a continuación

Excepción no controlada: System.Xml.XPath.XPathException: Gestor de espacio de nombres o XSLTC CONTEXTO necesario. Esta consulta tiene un prefijo, una variable o una función definida por el usuario.
en MS.Internal.Xml.XPath.CompiledXpathExpr.get_QueryTree() en System.Xml.XPath.XPathNavigator.Evaluate (XPathExpression expr, contexto Erator XPathNodeIt)
en System.Xml.XPath.XPathNavigator. evaluar (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); 

he intentado cambiar el código para insertar XmlNa mespaceManager 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); 

Se produce un error en XPathExpression.Compile invocación:

Excepción no controlada: System.Xml.XPath.XPathException: XsltContext se necesita para esta consulta porque de una función desconocida. en MS.Internal.Xml.XPath.CompiledXpathExpr.UndefinedXsltContext.ResolveFuncti en (String prefijo, String name, 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 de usar off-the-shelf XPath funciona con XPathExpression.Compile? Gracias

Respuesta

32

La funciónends-with()no está definido para XPath 1.0pero sólo para XPath 2.0 y XQuery.

Usted está usando .NET. . NET en esta fecha no implementaXPath 2.0, XSLT 2.0 o XQuery.

Uno puede construir fácilmente un XPath 1.0 expresión, la evaluación de los cuales 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()) como:

ends-with($str1, $str2)

En su caso concreto solo necesita sustituir el derecho e xpresiones para $str1 y $str2. Son, en consecuencia, /myXml/data y 'World'.

Por lo tanto, el XPath 1.0 expresión de usar, que es equivalente a la XPath 2.0 expresión ends-with(/myXml/data, 'World') es:

'World' = 
    substring(/myXml/data, 
      string-length(/myXml/data) - string-length('World') +1 
      ) 
Cuestiones relacionadas