Extract nodes from an XmlNodeList, with a namespace and where the same child will appear at multiple levels

I am trying to extract these subnodes, but so far I only had a headache ...

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <supplyCrew xmlns="http://site.ddf.com"> <login> <login>XXXX</login> <password>XXXX</password> </login> <flightInformation> <flights> <item> <arrivalDateTime>2010-11-08T22:48:00.000Z</arrivalDateTime> <arrivingCity>ORD</arrivingCity> <crewMembers> <item> <employeeId>020040</employeeId> <isDepositor>Y</isDepositor> <isTransmitter>N</isTransmitter> </item> <item> <employeeId>09000</employeeId> <isDepositor>N</isDepositor> <isTransmitter>Y</isTransmitter> </item> </crewMembers> </item> <item> <arrivalDateTime>2010-11-08T20:29:00.000Z</arrivalDateTime> <arrivingCity>JFK</arrivingCity> <crewMembers> <item> <employeeId>0538</employeeId> <isDepositor>Y</isDepositor> <isTransmitter>N</isTransmitter> </item> <item> <employeeId>097790</employeeId> <isDepositor>N</isDepositor> <isTransmitter>Y</isTransmitter> </item> 

with code that I can get, but I donโ€™t know how to select each of them according to their tag name in order to insert them into the database.

 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load("C:/Crew_Request_Sample.xml"); XmlNodeList elemList = xmlDoc.GetElementsByTagName("item"); foreach (XmlNode node in elemList) { Debug.WriteLine(node.InnerText); } 

I need some direction, please.

+7
source share
3 answers

The problem with using GetElementsByTagName("item") is that there are 2 levels of item node - one as a child of flights and the other as a child of crewMembers .

Edit Now that the full xml is inserted, it is clear that there is also a namespace. To handle namespaces, use the namespace manager to define namespace aliases that can then be used in xpath queries:

 var nsm = new XmlNamespaceManager(xmlDoc.NameTable); nsm.AddNamespace("s", "http://site.ddf.com"); var elemList = xmlDoc.SelectNodes("//s:crewMembers/s:item", nsm); foreach (var node in elemList) { Debug.WriteLine(node.SelectSingleNode("s:employeeId", nsm).InnerText); Debug.WriteLine(node.SelectSingleNode("s:isDepositor", nsm).InnerText); Debug.WriteLine(node.SelectSingleNode("s:isTransmitter", nsm).InnerText); } 
+7
source

You can do this with LINQ2XML ..

 XElement doc=XElement.Load("C:/Crew_Request_Sample.xml"); XNamespace e = "http://schemas.xmlsoap.org/soap/envelope/"; XNamespace s = "http://site.ddf.com"; //this would access the nodes of item->crewMembers->item and put it into an Anonymous Type var yourList=doc.Descendants(e+"Body") .Descendants(s+"supplyCrew") .Descendants(s+"flightInformation") .Descendants(s+"flights") .Descendants(s+"item") .Descendants(s+"crewMembers") .Descendants(s+"item") .Select( x=>new { //Anonymous Type employeeId=x.Element(s+"employeeId").Value, isDepositor=x.Element(s+"isDepositor").Value, isTransmitter=x.Element(s+"isTransmitter").Value } ); 

Then you can access your list using for each cycle

 foreach(var item in yourList) { Console.WriteLine(item.employeeId); Console.WriteLine(item.isDepositor); Console.WriteLine(item.isTransmitter); } 
+3
source

I think you will do it faster and easier using this technique.

Linq To XML

There are many examples on the site, so it will be easy for you to find what you want. Hope this helps.

+2
source

All Articles