Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading XML from Stream

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?

like image 553
Adam_G Avatar asked Jul 05 '13 20:07

Adam_G


2 Answers

@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>");
    }
}
like image 166
Lin Song Yang Avatar answered Oct 24 '22 22:10

Lin Song Yang


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)

like image 45
Thomas Levesque Avatar answered Oct 24 '22 20:10

Thomas Levesque