Domanda

Ho un'applicazione legacy che ho ereditato che passa un sacco di XML in giro come stringhe.

ho spesso bisogno la possibilità di controllare se una stringa sarà XML valido. Qual è il modo più veloce e costosa almeno per controllare se una stringa è XML valido in .NET?

sto lavorando in .NET 3.5 e molto probabilmente utilizzare questo come un metodo di estensione (fuori di corda) in questo progetto all'interno della soluzione.

Aggiorna :
Cosa voglio dire con XML "valido" nel mio caso è adeguatamente formata. Non ho bisogno di risorse convalidare o schema.

È stato utile?

Soluzione

Non è possibile convalidare la buona formulazione di una stringa XML senza analizzarlo. E un rapido spettacoli di riferimento che il modo più veloce per analizzare una stringa per vedere se è valido (in realtà il modo più veloce per analizzare la stringa particolare mi utilizzando come un banco di prova) è 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();
    }

Sulla mia macchina XmlReader è quasi due volte più veloce di qualsiasi delle alternative. Questo ha senso. Anche se non ho usato Reflector per verificare, sarei molto sorpreso se XmlDocument, XDocument, e XPathDocument non erano tutto utilizzando XmlReader sotto il cofano.

Altri suggerimenti

Io non sono a conoscenza di un built-in struttura in .NET per convalidare il formato-ness (?) Di XML senza analizzarlo. Dato che, qualcosa di simile a questo dovrebbe funzionare:

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;
        }
    }
}

D'accordo con Adam, e la versione 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;
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top