Reading XML from Stream
Asked Answered
C

2

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?

Candlestick answered 5/7, 2013 at 20:6 Comment(1)
What's the value of the string? It's probably that pesky FEFF...Kitti
D
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)

Denature answered 5/7, 2013 at 20:12 Comment(5)
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?Candlestick
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?Candlestick
@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" ?Denature
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?Candlestick
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...Denature
U
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>");
    }
}
Ultramicrometer answered 19/2, 2016 at 21:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.