C# XMLReader Strange 17th position closed XMLReader bug

375 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
SLaks 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
L.B 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
code4life 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