I’m developing a system to pick up XML attachments from emails, via Exchange Web Services, and enter them into a DB, via a custom DAL object that I’ve created.
I’ve manage to extract the XML attachment and have it ready as a stream… they question is how to parse this stream and populate a DAL object.
I can create an XMLTextReader and iterate through each element. I don’t see any problems with this other than that I suspect there is a much slicker way. The reader seems to treat the opening tag, the content of the tag and the closing tag as different elements (using reader.NodeType). I expected myValue to be considered one element rather than three. Like I said, I can get round this problem, but I’m sure there must be a better way.
I came across the idea of using an XML Serializer (completely new to me) but a quick look suggested that these can’t handle ArrayLists and List (I’m using List).
Again, I’m new to LINQ, but LINQ-to-XML has also been mentioned, but examples I’ve seen seem rather complex – though that my simply be my lack of familiarity.
Basically, I don’t want a cludged system, but I don’t want to use any complicated technique with a learning curve, just because it’s ‘cool’.
What is the simplest and most effective way of translating this XML/Stream in to my DAL objects?
XML Sample:
<?xml version="1.0" encoding="UTF-8"?>
<enquiry>
<enquiryno>100001</enquiryno>
<companyname>myco</companyname>
<typeofbusiness>dunno</typeofbusiness>
<companyregno>ABC123</companyregno>
<postcode>12345</postcode>
<contactemail>me@example.com</contactemail>
<firstname>My</firstname>
<lastname>Name</lastname>
<vehicles>
<vehicle>
<vehiclereg>54321</vehiclereg>
<vehicletype>Car</vehicletype>
<vehiclemake>Ford</vehiclemake>
<cabtype>n/a</cabtype>
<powerbhp>130</powerbhp>
<registrationdate>01/01/2003</registrationdate>
</vehicle>
</vehicles>
</enquiry>
Update 1:
I’m trying to deserialize, based on Graham’s example. I think I’ve set up the DAL for serialization, including specifying [XmlElement("whatever")] for each property. And I’ve tried to deserialize using the following:
SalesEnquiry enquiry = null;
XmlSerializer serializer = new XmlSerializer(typeof(SalesEnquiry));
enquiry = (SalesEnquiry)serializer.Deserialize(stream);
However, I get an exception:’There is an error in XML document (2, 2)‘. The innerexception states {"<enquiry xmlns=''> was not expected."}
Conclusion (updated):
My previous problem was the fact that the element in the XML file (Enquiry) != the name of the class (SalesEnquiry). Rather than an [XmlElement] attribute for the class, we need an [XmlRoot] attribute instead. For completeness, if you want a property in your class to be ignored during serialization, you use the [XmlIgnore] attribute.
I’ve successfully serialized my object, and have now successfully taken the incoming XML and de-serialized it into a SalesEnquiry object.
This approach is far easier than manually parsing the XML. OK, there has been a steep learning curve, but it was worth it.
Thanks!
If your XML uses a schema (i.e. you’re always going to know what elements appear, and where they appear in the tree), you could use
XmlSerializerto create your objects. You’d just need some attributes on your classes to tell the serializer what XML elements or attributes they correspond to. Then you just load up your XML, create a newXmlSerializerwith the type of the .NET object you want to create, and call theDeserializemethod.For example, you have a class like this:
And input XML like this (saved in a file for this example):
Then you create a
Personinstance like this:Update:
Based on your last update, I would guess that either you need to specify an
XmlRootattribute on the class that’s acting as your root element (i.e.SalesEnquiry), or theXmlSerializermight be a bit confused that you’re referencing an empty namespace in your XML (xmlns=''doesn’t seem right).