How to iterate through XDocument, get the full XML structure, object by object?

I have an XmlDocument with which I can navigate with an XmlNode or convert it to an XDocument and go through LINQ.

 <Dataset> <Person> <PayrollNumber>1234567</PayrollNumber> <Surname>Smith-Rodrigez</Surname> <Name>John-Jaime-Winston Junior</Name> <Skills> <Skill>ICP</Skill> <Skill>R</Skill> </Skills> <HomePhone>08 8888 8888</HomePhone> <MobilePhone>041 888 999</MobilePhone> <Email> curly@stooge.com </Email> </Person> <Person> <PayrollNumber>12342567</PayrollNumber> <Surname>Smith-Rodrigez</Surname> <Name>Steve</Name> <Skills> <Skill>Resus</Skill> <Skill>Air</Skill> </Skills> <HomePhone>08 8888 8888</HomePhone> <MobilePhone>041 888 999</MobilePhone> <Email> curly@stooge.com </Email> </Person> </Dataset> 

Question 1

I want to convert Person records / nodes to XML into a business object (POCO) object. Therefore, I have to iterate through the Person node at a time, and then parse the individual values. This last bit is interesting in itself, but first I have to get the actual Person entries. The problem is that if I select individual nodes (using the XmlList in the XmlDocoment ),

As a result, I aggregate all the fields by name. I am interested in doing this if one of the user nodes is incomplete or even missing, and then I will not know what is missing when I pass and merge fields into business objects. I will try and check - see Question 2.

I understand that this can be done through reflection, but I'm interested.

I tried iterating through the Person object:

Option 1:

 foreach (XObject o in xDoc.Descendants("Person")) { Console.WriteLine("Name" + o); // [...] } 

This gives me 2 person entries (correct) for each string full XML document formatted as an XML document. Just a subset of the above XML document.

But how to break a record into separate nodes or fields - preferably as painlessly as possible?

Option 2:

 foreach (XElement element in xDoc.Descendants("Person")) { // [...] } 

This gives me the XML nodes - only the values ​​- for each Person everything is on the same line, for example.

1234567Smith-RodrigezJohn-Jaime-Winston JuniorLevel 5, City Central Tower 2, 121 King William StNorth Adelaide 5000ICPR08 8888 8888041 888 999111111curly@stooge.comE

Again, little use.

Question 2

I can check the XDocument quite easily, there are some good examples on MSDN, but I would like to know how I can flag the wrong entry. Ideally, I would like to permanently XDocument good entries on the new XDocument , leaving the old ones behind. Is it possible?

+4
source share
2 answers

The problem is that you are simply printing the elements as strings. You need to write code to convert the XElement of <Person> to your business object. Admittedly, I would expect the full XML to be written out instead - are you sure you are not printing XElement.Value (which combines all descendant text nodes)?

(I’m not sure about the answer to your second question - I suggest you ask it as a separate question here, so that we don’t get a mixture of answers on one page.)

+4
source

Why not use XML deserialization?

There are two ways to do this.

  • The first of these is to modify the Person business object to match this XML by adding the appropriate attributes to the Person class and its properties. XML is pretty straightforward, so you probably just need to change the names if there is no 1: 1 correspondence between the properties of the object and the XML nodes. For example, you must specify [XmlArray("Skills")] and [XmlArrayItem("Skill)] for the Skills collection.

  • The second is to convert the given XML to one that matches the default serialization of your Person object, and then for deserialization.

The second solution will also give you the ability to very easily filter β€œbad” records.

+1
source

All Articles