views:

86

answers:

2

Hi,

I have a very large XML file that I need to parse so I need to use XMLReader. This file contains a large number of second level elements that contain the information I'm interested in e.g.:

<topLevelElement>
  <SecondLevelElement>
    <Information1>blah</Information1>
    <Information2>blah</Information2>
    <Information3>blah</Information3>
  </SecondLevelElement>
  <SecondLevelElement>
  ....
</topLevelElement>

The individual second level elements are not very large so I'd be happy to load each one individually as an object and would prefer this to structuring my reader code based on the schema of the file I'm trying to parse.

I've used xsd.exe to create objects from my schema and tried this:

while(lReader.Read())
{
  if (lReader.Name == "SecondLevelElement")
  {
    MyXml.SecondLevelElement lSecondLevelElement = lReader.ReadElementContentAs(typeof(MyXml.SecondLevelElement), null) as MyXml.SecondLevelElement;

    if (lSecondLevelElement != null)
    {
      // Do stuff
    }
  }
}

But it fails with a not very helpful exception in ReadElementContentAs(). The examples in MSDN only show this method used on very basic data types so I'm not entirely sure that I can even do this.

So my first question is is this even possible, or am I wasting my time barking up completely the wrong tree? If I am wrong is there a way of parsing the XML sections without structuring my reading code to closely match the XSD?

EDIT After applying Pavel's answer I got deserialization errors. In my case that was down to the XSD I was using to auto generate the classes. Because I had an XSD for the whole document the second level element class name didn't match the actual element name. To fix this I removed the top level element from my XSD schema and regenerated the classes. After doing that it all worked perfectly.

A: 

If the sub chunks of XML conform to an XSD then you can certainly turn them into functional objects. I wrote about this in great detail here:

http://blog.andrewsiemer.com/archive/2008/04/30/accepting-xmldocuments-from-biztalk-de-serializing-them-to-xsd-generated-serializable.aspx

Andrew Siemer
+2  A: 

ReadElementContentAs only works with a predefined set of mostly primitive types like int, DateTime etc. It's not to be used with types generated by xsd.exe - those are handled by XmlSerializer:

private static readonly XmlSerializer secondLevelElementSerializer = 
    new XmlSerializer(typeof(MyXml.SecondLevelElement));
...
XmlReader reader;
while (reader.Read())
{
    ...
    switch (reader.Name)
    {
        case "SecondLevelElement":
            {
                 MyXml.SecondLevelElement elem = (MyXml.SecondLevelElement)
                      secondLevelElementSerializer.Deserialize(reader);
                 ...
            } break;
        ...
    }
}
Pavel Minaev