Check well-formed XML without a try/catch?

Does anyone know how I can check if a string contains well-formed XML without using something like XmlDocument.LoadXml() in a try/catch block? I've got input that may or may not be XML, and I want code that recognises that input may not be XML without relying on a try/catch, for both speed and on the general principle that non-exceptional circumstances shouldn't raise exceptions. I currently have code that does this;

private bool IsValidXML(string value)
    {
        try
        {
            // Check we actually have a value
            if (string.IsNullOrEmpty(value) == false)
            {
                // Try to load the value into a document
                XmlDocument xmlDoc = new XmlDocument();

                xmlDoc.LoadXml(value);

                // If we managed with no exception then this is valid XML!
                return true;
            }
            else
            {
                // A blank value is not valid xml
                return false;
            }
        }
        catch (System.Xml.XmlException)
        {
            return false;
        }
    }

But it seems like something that shouldn't require the try/catch. The exception is causing merry hell during debugging because every time I check a string the debugger will break here, 'helping' me with my pesky problem.


I don't know a way of validating without the exception, but you can change the debugger settings to only break for XmlException if it's unhandled - that should solve your immediate issues, even if the code is still inelegant.

To do this, go to Debug / Exceptions... / Common Language Runtime Exceptions and find System.Xml.XmlException, then make sure only "User-unhandled" is ticked (not Thrown).


Steve,

We had an 3rd party that accidentally sometimes sent us JSON instead of XML. Here is what I implemented:

public static bool IsValidXml(string xmlString)
{
    Regex tagsWithData = new Regex("<\\w+>[^<]+</\\w+>");

    //Light checking
    if (string.IsNullOrEmpty(xmlString) || tagsWithData.IsMatch(xmlString) == false)
    {
        return false;
    }

    try
    {
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.LoadXml(xmlString);
        return true;
    }
    catch (Exception e1)
    {
        return false;
    }
}

[TestMethod()]
public void TestValidXml()
{
    string xml = "<result>true</result>";
    Assert.IsTrue(Utility.IsValidXml(xml));
}

[TestMethod()]
public void TestIsNotValidXml()
{
    string json = "{ \"result\": \"true\" }";
    Assert.IsFalse(Utility.IsValidXml(json));
}