0
votes

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>
2
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 - Mechanical Object

2 Answers

1
votes

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);
0
votes

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.