2

How do i know if my XML file has data besides the name space info:

Some of the files contain this:

<?xml version="1.0" encoding="UTF-8"?>

And if i encounter such a file, i want to place the file in an error directory

7 Answers 7

4

You could use the XmlReader to avoid the overhead of XmlDocument. In your case, you will receive an exception because the root element is missing.

string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
using (StringReader strReader = new StringReader(xml))
{
    //You can replace the StringReader object with the path of your xml file.
    //In that case, do not forget to remove the "using" lines above.
    using (XmlReader reader = XmlReader.Create(strReader))
    {
        try
        {
            while (reader.Read())
            {
            }
        }
        catch (XmlException ex)
        {
            //Catch xml exception
            //in your case: root element is missing
        }
    }
}

You can add a condition in the while(reader.Read()) loop after you checked the first nodes to avoid to read the entire xml file since you just want to check if the root element is missing.

Sign up to request clarification or add additional context in comments.

5 Comments

+1 but catch XmlException in the catch block instead of just Exception.
Might also just use XmlReader.Create('filename') overload instead of passing in StringReader to avoid having to load the body of xml into memory first, otherwise your not gaining much over convenience of XmlDocument, if any...though i'm only on my first cup o coffee so take that with a grain of salt! :)
I agree with you. In that case, I just use the stringreader to use the xml sample provided by itech.
If you only care if you can read the file you could just make it a method and return reader.Reader() and in the XmlException you could return false;
If you're only concerned about empty XML documents you can use reader.MoveToContent(); instead of the while(reader.Read()) {}
2

I think the only way is to catch an exception when you try and load it, like this:

   try
    {
        System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
        doc.Load(Server.MapPath("XMLFile.xml"));
    }
    catch (System.Xml.XmlException xmlEx)
    {
        if (xmlEx.Message.Contains("Root element is missing"))
        {
            // Xml file is empty
        }
    }

Yes, there is some overhead, but you should be performing sanity checks like this anyway. You should never trust input and the only way to reliably verify it is XML is to treat it like XML and see what .NET says about it!

Comments

2

XmlDocument xDoc = new XmlDocument();

if (xDoc.ChildNodes.Count == 0) { // xml document is empty }

if (xDoc.ChildNodes.Count == 1) { // in xml document is only declaration node. (if you are shure that declaration is allways at the begining }

if (xDoc.ChildNodes.Count > 1) { // there is declaration + n nodes (usually this count is 2; declaration + root node) }

Comments

1

Haven't tried this...but should work.

try
{
    XmlDocument doc = new XmlDocument();
    doc.Load("test.xml");
}
catch (XmlException exc)
{
    //invalid file
}

EDIT: Based on feedback comments

For large XML documents see Thomas's answer. This approach can have performance issues. But, if it is a valid xml and the program wants to process it then this approach seems better.

5 Comments

I thought about this, but what is the overhead difference between loading the XML and doing what I suggested? This is definitely more clear, but I'm just curious about performance, especially with large XML documents - why load the XML if you don't need it?
+1 Thomas, I agree to your point about NOT using my approach for large XML documents. But, if it is a valid xml and the program wants to process it then this approach seems better.
That's very true. I think you should add that to your post, I'll add something similar to mine as well.
PK - that won't work. You'll get an exception as soon as you try and load the document.
Your correct about the overhead of performance - especially with documents >= 85K in size. But I'm betting that poster needs to know more about the contents of that file than whether there is any data beyond the processing instructions (e.g. valid xml). XmlReader will keep a flatter memory model in this situation and give benefits of easily determining if valid xml.
0

If you aren't worried about validity, just check to see if there is anything after the first ?>. I'm not entirely sure of the C# syntax (it's been too long since I used it), but read the file, look for the first instance of ?>, and see if there is anything after that index.

However, if you want to use the XML later or you want to process the XML later, you should consider PK's answer and load the XML into an XmlDocument object. But if you have large XML documents that you don't need to process, then a solution more like mine, reading the file as text, might have less overhead.

Comments

0

You could check if the xml document has a node (the root node) and check it that node has inner text or other children.

Comments

0

As long as you aren't concerned with the validity of the XML document, and only want to ensure that it has a tag other than the declaration, you could use simple text processing:

var regEx = new RegEx("<[A-Za-z]");
bool foundTags = false;
string curLine = "";

using (var reader = new StreamReader(fileName)) {
    while (!reader.EndOfStream) {
       curLine = reader.ReadLine();
       if (regEx.Match(curLine)) {
           foundTags = true;
           break;
       }
    }
}

if (!foundTags) {
    // file is bad, copy.
}

Keep in mind that there's a million other reasons that the file may be invalid, and the code above would validate a file consisting only of "<a". If your intent is to validate that the XML document is capable of being read, you should use the XmlDocument approach.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.