valor saber obtener nodo leer existe especifico ejemplos buscar c# xml xpath searching-xml

saber - obtener valor de un nodo xml c#



¿Cuál es una buena manera de encontrar un valor específico en un documento XML usando C#? (6)

Fuera de mi cabeza, lo siguiente debería funcionar:

XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; XmlNamespaceManager mgr = GetNamespace(doc); doc.LoadXml(xmltext); XmlNode nd = doc.DocumentElement.SelectSingleNode("//ns0:result", mgr);

El código de espacio de nombres se ve así:

private XmlNamespaceManager GetNamespace(XmlDocument document) { XmlNamespaceManager mgr = new XmlNamespaceManager(document.NameTable); mgr.AddNamespace("ns0", "http://dev1/MyWebService1.wsdl"); return mgr; }

Necesita usar el administrador del espacio de nombres porque el documento XML tiene espacios de nombres asociados, y XPath usa esto en la resolución de la consulta.

Estoy llamando a un servicio web expuesto por Oracle que acepta una entrada de un ID de artículo y me devuelve el número de artículo correspondiente. Quiero obtener el Número de artículo que se ha devuelto del XML contenido en la respuesta.

El XML se ve así:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://dev1/MyWebService1.wsdl"> <env:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" env:mustUnderstand="1"/> </env:Header> <env:Body> <ns0:getItemNbrByItemIdResponseElement> <ns0:result>1010603</ns0:result> </ns0:getItemNbrByItemIdResponseElement> </env:Body> </env:Envelope>

Estoy interesado en obtener solo <ns0:result>1010603</ns0:result> especialmente solo el 1010603.

No he trabajado mucho analizando XML usando C # y estoy jugando con algunos métodos diferentes hasta ahora. cual es la manera recomendada para hacer esto?

Estoy en VS2008 (por lo que XPath está disponible, etc.)


Hay respuestas muy buenas y completas a esta pregunta.

Agregaría solo por curiosidad, que una expresión XPath extremadamente simple hace el trabajo en este caso particular:

normalize-space(/)

Esto se hace fácilmente en C # utilizando algo así como las dos líneas a continuación:

XPathNavigator navigator = document.CreateNavigator(); string res = (string)navigator.Evaluate("normalize-space(/)");

Con la buena optimización del motor XPath de .NET, su evaluación puede ser incluso eficiente.


Para resolver esto, utilicé la respuesta de Jon Skeet. Este es el código que tuve que implementar para que esto funcione (para el beneficio futuro de cualquier otra persona).

XmlDocument xmlDoc = new XmlDocument(); XNamespace ns0 = "http://dev1/MyWebService1.wsdl"; xmlDoc.Load(request.GetResponse().GetResponseStream()); XDocument xDoc = XDocument.Load(new XmlNodeReader(xmlDoc)); String result = xDoc.Descendants(ns0 + "result").First().Value;

Por supuesto, esto supone que recibo mi respuesta de una solicitud con nombre HttpWebRequest.


Puede engañar el problema del espacio de nombres con un xpath como este: //*[local-name()=''result'']


Si no quiere ir a Linq, puede usar XPathDocument para recuperar el valor:

XPathDocument xmldoc = new XPathDocument(@"C:/tmp/sample.xml"); XPathNavigator nav = xmldoc.CreateNavigator(); XmlNamespaceManager nsMgr = new XmlNamespaceManager(nav.NameTable); nsMgr.AddNamespace("ns0", "http://dev1/MyWebService1.wsdl"); XPathNavigator result = nav.SelectSingleNode("//ns0:result", nsMgr); System.Diagnostics.Debug.WriteLine(result.Value);

XPathDocument tiene una huella de memoria menor y es más probable que sea más rápido en su escenario que XmlDocument. XmlDocument crea un modelo de objeto completo de su documento XML en memoria, mientras que XPathDocument no lo hace.


Yo personalmente usaría LINQ to XML, porque me parece más fácil de tratar que XPath, particularmente cuando se trata de espacios de nombres. Harías algo como:

XNamespace ns0 = "http://dev1/MyWebService1.wsdl"; String result = doc.Descendants(ns0 + "result").First().Value;

Tenga en cuenta que se espera que doc aquí sea un XDocument , no un XmlDocument . (Creo que es por eso que no se presentó para usted).