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

Foi útil?

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 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' .

Assim, a expressão XPath 1.0 para utilização, que é equivalente à expressão ends-with(/myXml/data, 'World') XPath 2.0 é :

'World' = 
   substring(/myXml/data,
             string-length(/myXml/data) - string-length('World') +1
             )
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top