C# XMLReader Strange 17th position closed XMLReader bug

357 Views Asked by At

I have a ListView that has a bunch of stuff. Whatever is in the 17th spot always breaks (ObjectDisposedException "Cannot read from a closed TextReader"). 1 through 16 as well as 18 through 24 work fine. If I move x from 17th to 16th, it'll work again, but the new 17th breaks. My code doesn't refer to any places specifically.

The XML file follows the format

<Profiles>
  <Profile name="a" type="A">
    <ListOne>1,2,3,4,5,6,7,8</ListOne>
    <ListTwo>1,2,3,4,5,6,7,8</ListTwo>
  </Profile>
  <Profile name="b" type="B">
    ...
    ...
</Profiles>

The code is simple. I have a method to find the profile I'm interested in and return it as a subtree

string CurrentProfile = "";
using (StreamReader SR = new StreamReader(MyXMLFilePath))
{
  XmlTextReader TR = new XmlTextReader(SR);
  do
  {
    TR.ReadToFollowing("Profile");
    TR.MoveToFirstAttribute();
    CurrentName = TR.Value;
    TR.MoveToNextAttribute();
    string CurrentType = TR.Value;

    if (CurrentName == MyName && CurrentType == MyType)
    {
      TR.MoveToElement();
      XmlReader subtree = TR.ReadSubtree();
      return subtree;
    }
  }
  while (CurrentName != "");
}

And then I have a method that pulls out lists 1 and 2 from the subtree.

if(subtree != null)
{
  subtree.ReadToFollowing("ListOne");
  subtree.Read();
  string[] ListOneArray = subtree.Value.Split(',');

  subtree.ReadToFollowing("ListTwo");
  subtree.Read();
  string[] ListTwoArray = subtree.Value.Split(',');
}

And that's where the problem occurs. ObjectDisposedException Cannot read from a closed TextReader. It always breaks when I get to subtree.ReadToFollowing("ListTwo") but only if I'm selecting the 17th profile in the XML List. I don't see how I'm closing the textreader at any point. Also, this works for profile 18, 19, 20, etc. as well as 1 through 16, but somehow always breaks at position 17 regardless of what's in there. I don't see how the 17th spot is any different from any others.

Help please!

3

There are 3 best solutions below

1
On

ReadSubTree() returns a reader that still reads from the underlying stream.
Since you close the stream before reading from that reader, it won't work.

In general, the forward-only model of XmlReader is rather annoying to work with.
Unless you're dealing with very large files, you should use LINQ to XML instead; it's much easier to use.

0
On

I personally find using Linq2Xml much easier when working with xmls

XDocument xDoc = XDocument.Load(...);
var profiles = xDoc.Descendants("Profile")
    .Where(x=>x.Attribute("name").Value=="a")
    .Select(p => new
    {
        List1 = p.Element("ListOne").Value.Split(','),
        List2 = p.Element("ListTwo").Value.Split(',')
    })
    .ToList();
0
On

Where are you closing the subtree? Based on the MSDN documentation, just wondering if the best practice might be to close the subtree XmlReader explicitly somewhere in the code.

http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.readsubtree.aspx