0

I am reading a huge XML file (250 MB) using XMLReader and add only specific elements to a generic List . I am unable to add values to the list correctly.I am getting null values in the List.I'll appreciate your help Below is the class I am using :

public class SomeInfo
    {
       public string Item1 { get; set; }

       public string Item2 { get; set; }

    }

My code to read XML is as below :

using (XmlReader reader = XmlReader.Create(file)
                )
            {
                List<SomeInfo> test = new List<SomeInfo>();

                while (reader.Read())
                {
                    var testObject = new SomeInfo();
                    if (reader.NodeType == XmlNodeType.Element)
                    {

                        string name = reader.Name;
                        switch (name)
                        {
                            case "Item1":
                                reader.Read();
                                testObject.item1= reader.Value;
                                break;
                            case "Item2":
                                reader.Read();
                                testObject.item2= reader.Value;
                                break;
                        }
            test.Add(testObject);
                    }

                    }

Sample XML : This is huge xml file and I only need to read some elements and add to the list .In my code above, I am only reading Item1 and Item2 and do not care about Xitem,Bitem and Citem tags

<mainItem>
<Item>
      <Xitem>125</Xitem>
      <Item1>ab41gh80020gh140f6</Item1>
      <BItem>42ae3de3</BItem>
      <Item2>7549tt80384</Item2>
      <Citem>c7dggf66e4</Citem>
</Item>
<Item>
      <Xitem>865</Xitem>
      <Item1>ab41gh80020gh140f6</Item1>
      <BItem>42aejj3de3</BItem>
      <Item2>7549kljj80384</Item2>
      <Citem>c7df6kk6e4</Citem>
</Item>
<Item>
      <Xitem>895</Xitem>
      <Item1>ab41gjgjgh80020gh140f6</Item1>
      <BItem>42aehkh3de3</BItem>
      <Item2>754980384</Item2>
      <Citem>c7dfjj66e4</Citem>
</Item>
    </mainItem>
user1110790
  • 787
  • 2
  • 8
  • 27
  • `reader.Read()` reads the next node from the stream. In your algorithm, for each node like `mainItem,XItem, Item1` you are creating an instance of `SomeInfo` class. So your list will have 19 elements instead of 3. I would suggest you to [try deserialize xml](http://stackoverflow.com/questions/364253/how-to-deserialize-xml-document) – Mechanical Object Jul 25 '13 at 05:53

2 Answers2

1

change as below

private List<SomeInfo> ProcessItems(XmlTextReader reader)
{
    List<SomeInfo> test = new List<SomeInfo>();
    while (reader.Read())
    {
        if (reader.Name.Equals("Item"))
        {
            var testObject = new SomeInfo();
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("Item"))
                {
                    break;
                }
                if (reader.NodeType == XmlNodeType.Element)
                {
                    switch (reader.Name)
                    {
                        case "Item1":
                            testObject.Item1 = reader.ReadString();
                            break;
                        case "Item2":
                            testObject.Item2 = reader.ReadString();
                            break;
                    }
                }
            }
            test.Add(testObject);

        }
    }
    return test;

}

Usage :

XmlTextReader reader = new XmlTextReader(filepath));
List<SomeInfo> result = ProcessItems(reader);
Damith
  • 62,401
  • 13
  • 102
  • 153
  • I tried this approach and it creates two rows for each item in the List . If the xml contains 1 value of each , then by using the above Code , the list will contain 2 rows having item1=somevalue,item2=null and item1=null and item2=somevalue.Any ideas how to get around that ? – user1110790 Jul 25 '13 at 05:10
0

Are you having null values for Item1 or Item2 or is it that you see null values in the test list.

The culprit seems to be your code which is in a way that, every time the traversed node is an XmlNodeType.Element, you are adding the object to the list. Based on the your switch; if element is of type Item1, then Item2 will be null in the test object and for Item2 type, Item1 will be null always. Also, if your code have more element types, then objects which have both values as null would be inserted into your test object.

Prash
  • 1,122
  • 1
  • 8
  • 10