0

I am trying to read the nested elements in the xml below. So far I have been able to read data in chantier/data element, but now the problem lies in how can I read the data inside <questions><sitePreparation> and <ctm>? Xml file and code have been shorted a bit because they are too long. Any help is much appreciated.

<?xml version="1.0" encoding="UTF-8"?> <Audit> <controls> <guid> 0001 </guid> <templateVersion> 1.0 </templateVersion> </controls> <chantier> <data> <V2>V2</V2> <V3>V3</V3> <V3_1>V3_1</V3_1> <V4>V4</V4> <oresTiersPanel> <S1_2>S1_2</S1_2> </oresTiersPanel> <agentsTiersPanel> <S1_2_2>S1_2_2</S1_2_2> </agentsTiersPanel> </data> <questions> <sitePreparation> <P1_Question>P1_Q</P1_Question> <P6_Question>P6_Q</P6_Question> </sitePreparation> <ctm> <C1_Question>C1_Q</C1_Question> <C2_Question>C2_Q</C2_Question> <C2_1>C2_1</C2_1> </ctm> </questions> </chantier> </Audit> 

private static void ReadXml() { XDocument xdoc = XDocument.Load("sipp.xml"); if (xdoc.Root != null) { var chantier = from ch in xdoc.Root.Elements("chantier").Elements("data") let agentsTiersPanel = ch.Element("agentsTiersPanel") where agentsTiersPanel != null select new { v2 = (string)ch.Element("V2"), v3 = (string)ch.Element("V3"), v3_1 = (string)ch.Element("V3_1"), v4 = (string)ch.Element("V4"), S1_2_2 = (string)agentsTiersPanel.Element("S1_2_2"), S1_2_2_1 = (string)agentsTiersPanel.Element("S1_2_2_1"), S1_2_3 = (string)agentsTiersPanel.Element("S1_2_3"), S3 = (string)ch.Element("S3"), S3_1 = (string)ch.Element("S3_1"), P1_Question = (string)ch.Element("P1_Question") }; foreach (var item in chantier) { Console.WriteLine(item.v2 + " " + item.v3); } } } 
5
  • How do you read data in chantier/data? Commented Jun 6, 2014 at 8:03
  • Kindly review these Questions : stackoverflow.com/questions/13203975/… , stackoverflow.com/questions/11758904/… ... Hope this helps .. Cheers! Commented Jun 6, 2014 at 8:06
  • Looks fine. So, what's your problem with reading questions? Use same approach Commented Jun 6, 2014 at 8:07
  • I have tried different methods either I get nothing or I get an exeption. Can you give me an example? Commented Jun 6, 2014 at 8:12
  • Then show the attempt and the exception details. Commented Jun 6, 2014 at 8:38

2 Answers 2

0

Sample of reading questions elements:

var questions = xdoc.Root.Elements("chantier") .Elements("questions").FirstOrDefault(); if (questions != null) { var sitePreparation = questions.Element("sitePreparation"); if (sitePreparation != null) { Console.WriteLine((string)sitePreparation.Element("P1_Question")); Console.WriteLine((string)sitePreparation.Element("P6_Question")); } } 

If you want return P1 and P6 questions as part of your anonymous object, then keep in mind, that ch is a data element of chantier, not chantier element itself. That's why ch.Element("P1_Question") returns null. With skipping null elements query should look like:

var chantiers = from chantier in xdoc.Root.Elements("chantier") let data = chantier.Element("data") let questions = chantier.Element("questions") where data != null && questions != null select new { V2 = (string)data.Element("V2"), V3 = (string)data.Element("V3"), V3_1 = (string)data.Element("V3_1"), V4 = (string)data.Element("V4"), S1_2_2 = (string)data.Element("agentsTiersPanel").Element("S1_2_2"), P1_Question = (string)questions.Element("sitePreparation") .Element("P1_Question") }; 

Output:

[ { V2: "V2", V3: "V3", V3_1: "V3_1", V4: "V4", S1_2_2: "S1_2_2", P1_Question: "P1_Q" } ] 
Sign up to request clarification or add additional context in comments.

2 Comments

is it possible to read the elements in the first loop without creating a second one? I would like to know if it is possible to navigate up the elements and then navigate down to the right element?
Thanks Sergey, your example helped me understand how Linq reads the xml.
0

It might be easier to deserialize it into an object. You can use the Paste special feature within VS to get a class representation of your XML structure. From there, it is pretty straightforward as far as deserialization goes:

private Audit GetAuditNodes() { Audit audit = null; XmlSerializer serializer = new XmlSerializer(typeof(Audit)); string uri = "data.xml"; try { XmlReaderSettings settings = new XmlReaderSettings(); settings.CheckCharacters = false; settings.CloseInput = true; settings.DtdProcessing = DtdProcessing.Ignore; settings.IgnoreComments = true; settings.IgnoreWhitespace = true; using (XmlReader reader = XmlReader.Create(uri, settings)) { audit = (Audit)serializer.Deserialize(reader); } } catch (Exception exc) { //log an error or something } return audit; } 

You have much cleaner code and can also work with a strongly typed object

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.