Pregunta

Tengo una aplicación heredada que heredé que pasa una gran cantidad de alrededor de XML como cadenas.

A menudo necesitan la capacidad de comprobar si una cadena será XML válido. ¿Cuál es la manera más rápida y menos costosa para comprobar si una cadena es XML válido en .NET?

Estoy trabajando en .NET 3.5 y lo más probable es utilizar esto como un método de extensión (fuera de la cadena) en este un proyecto dentro de la solución.

Actualizar :
Lo que quiero decir con XML "válida" en mi caso se forma correctamente. No necesito a los recursos validar o esquema.

¿Fue útil?

Solución

No es posible validar la correcta formación de una cadena XML sin analizarlo. Y una rápida muestra de referencia que la manera más rápida para analizar una cadena para ver si es válida (en realidad la forma más rápida de analizar la cadena en particular I utilizando como caso de prueba) es con un XmlReader:

    static void Main(string[] args)
    {
        const int iterations = 20000;
        const string xml = @"<foo><bar><baz a='b' c='d'/><foo><bar><baz a='b' c='d'/></bar><bar/></foo><foo><bar><baz a='b' c='d'/></bar><bar/></foo><foo><bar><baz a='b' c='d'/></bar><bar/></foo><foo><bar><baz a='b' c='d'/></bar><bar/></foo><foo><bar><baz a='b' c='d'/></bar><bar/></foo><foo><bar><baz a='b' c='d'/></bar><bar/></foo><foo><bar><baz a='b' c='d'/></bar><bar/></foo><foo><bar><baz a='b' c='d'/></bar><bar/></foo><foo><bar><baz a='b' c='d'/></bar><bar/></foo></bar><bar/></foo>";

        Stopwatch st = new Stopwatch();

        st.Start();
        for (int i=0; i<iterations; i++)
        {
            using (StringReader sr = new StringReader(xml))
            using (XmlReader xr = XmlReader.Create(sr))
            {
                while (xr.Read())
                {
                }
            }
        }
        st.Stop();
        Console.WriteLine(String.Format("XmlReader: {0} ms.", st.ElapsedMilliseconds));

        st.Reset();
        st.Start();
        for (int i=0; i<iterations; i++)
        {
            XElement.Parse(xml);
        }
        st.Stop();
        Console.WriteLine(String.Format("XElement: {0} ms.", st.ElapsedMilliseconds));

        st.Reset();
        st.Start();
        for (int i = 0; i < iterations; i++)
        {
            XmlDocument d= new XmlDocument();
            d.LoadXml(xml);
        }
        st.Stop();
        Console.WriteLine(String.Format("XmlDocument: {0} ms.", st.ElapsedMilliseconds));

        st.Reset();
        st.Start();
        for (int i = 0; i < iterations; i++)
        {
            using (StringReader sr = new StringReader(xml))
            {
                XPathDocument d = new XPathDocument(new StringReader(xml));                    
            }
        }
        st.Stop();
        Console.WriteLine(String.Format("XPathDocument: {0} ms.", st.ElapsedMilliseconds));

        Console.ReadKey();
    }

En mi máquina XmlReader es casi el doble de rápido que cualquiera de las alternativas. Esto tiene sentido. Aunque no he utilizado reflector para comprobar, estaría muy sorprendido si XmlDocument, XDocument y XPathDocument no eran todas ellas con XmlReader bajo el capó.

Otros consejos

No estoy al tanto de un sistema incorporado en las instalaciones de .NET para validar la forma-ción (?) De XML sin analizarlo. Teniendo en cuenta que, algo como esto debería funcionar:

public static class XmlUtilities
{
    public static bool IsXml(this string data)
    {
        if (string.IsNullOrEmpty(data)) return false;

        try
        {
            System.Xml.XmlDocument doc = new System.Xml.XmlDocument();

            doc.LoadXml(data);

            return true;            
        }
        catch
        {
            return false;
        }
    }
}

De acuerdo con Adán, y la versión XElement:

public static class XmlUtilities
{

    public static bool IsXml(this string data)
    {
        if (string.IsNullOrEmpty(data)) return false;

        try
        {
            var doc = XElement.Parse(data)

            return true;            
        }
        catch (XmlException)
        {
            return false;
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top