11

I'm working with ASP.NET, and am importing an XML file from a form. Right now I convert that into a Stream:

Stream inputStream = XmlFileUploadControl.PostedFile.InputStream;

because I may need this version later.

I'd like to first check to make make sure that the XML file has the correct format, and, if it is, then display some information:

if (CorrectFileFormat(inputStream))
{
    DisplayLicenseInfo(inputStream);
}

else
{
    StatusLabel.Text = "Selected file is not a LicensingDiag XML file";
}

The CorrectFileFormat() method:

protected Boolean CorrectFileFormat(Stream inputStream)
{

    XmlReader reader = XmlReader.Create(inputStream);

    if (reader.MoveToContent() == XmlNodeType.Element && reader.Name == "DiagReport")
    {
        return true;
    }
}

The DisplayLicenseInfo() method:

protected void DisplayLicenseInfo(Stream inputStream)
{

    XmlReader reader = XmlReader.Create(inputStream);

    if (reader.MoveToContent() == XmlNodeType.Element && reader.Name == "LicensingStatus")
    {
        StatusLabel.Text += ("Licensing Status: " + reader.ReadString() + "<br><br>");
    }

}

However, I'm encountering an XmlException that says "Data at the root level is invalid. Line 1, position 1". Is this because I've already read through the input stream once, and need to reset it? If so, how do I do that?

svick
  • 236,525
  • 50
  • 385
  • 514
Adam_G
  • 7,337
  • 20
  • 86
  • 148

2 Answers2

8

The first time you create an XmlReader around the stream, it is at position 0. But the second time you create an XmlReader, the stream has already been partially read, so it is no longer at position 0, so the XmlReader can't read the XML document.

Instead, you should create the XmlReader only once:

using (XmlReader reader = XmlReader.Create(inputStream)
{
    if (CorrectFileFormat(reader))
    {
        DisplayLicenseInfo(reader);
    }
    else
    {
        StatusLabel.Text = "Selected file is not a LicensingDiag XML file";
    }
}

If the file is small, you could also consider loading the entire XML document using XmlDocument or XDocument (Linq to XML)

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • Thanks, that's what I was wondering. Aren't there issues with reading into an `XmlReader` object, as would be done in the first method, or would the 2nd method still start at the beginning? – Adam_G Jul 05 '13 at 20:57
  • While this definitely goes in the rightt direction, and gets me to the Display() method, it then does something to the statement I execute in that method, where it no longer works. Any ideas? – Adam_G Jul 05 '13 at 22:09
  • @Adam_G, the second method that uses the same reader would continue from the current position. Regarding your second question, you need to be more precise... what do you mean by "it does something to the statement" ? And how exactly does it "no longer work" ? – Thomas Levesque Jul 05 '13 at 22:21
  • When I say "it doesn't work," I mean that the `if...` statement in method 2 used to evaluate to `True`, but now evaluates to `False`. So, whether the `Stream` or the `XmlReader` is partially reading into the document, it doesn't really get us anywhere. Am I missing something? – Adam_G Jul 06 '13 at 00:16
  • Well, I guess it depends on what you're trying to do... Anyway, loading the full XML as an XDocument would make your life much easier... – Thomas Levesque Jul 06 '13 at 01:02
6

@thomas-levesque https://stackoverflow.com/users/98713/thomas-levesque was right, if the content itself is well-formed, then you need to rewind the stream back to the start of the content.

The CorrectFileFormat() method:

protected Boolean CorrectFileFormat(Stream inputStream)
{
    // rewind the stream back to the very beginning of the content
    inputStream.Seek(0L, SeekOrigin.Begin);
    XmlReader reader = XmlReader.Create(inputStream);

    if (reader.MoveToContent() == XmlNodeType.Element && reader.Name == "DiagReport")
    {
        return true;
    }
}

The DisplayLicenseInfo() method:

protected void DisplayLicenseInfo(Stream inputStream)
{
    // rewind the stream back to the very beginning of the content
    inputStream.Seek(0L, SeekOrigin.Begin);
    XmlReader reader = XmlReader.Create(inputStream);

    if (reader.MoveToContent() == XmlNodeType.Element && reader.Name == "LicensingStatus")
    {
        StatusLabel.Text += ("Licensing Status: " + reader.ReadString() + "<br><br>");
    }
}
Community
  • 1
  • 1
Lin Song Yang
  • 1,936
  • 19
  • 17