Frage

Ich habe eine Legacy-Anwendung, dass ich geerbt, die eine Menge von XML läuft um als Strings.

Ich brauche oft die Möglichkeit, zu überprüfen, ob ein String gültiges XML sein. Was ist der schnellste und kostengünstigste Weg, um zu überprüfen, ob eine Zeichenfolge in .NET gültige XML ist?

Ich bin in .NET 3.5 zu arbeiten und würde höchstwahrscheinlich diese verwendet als Erweiterung Methode (off von string) in diesem Projekt in der Lösung.

UPDATE :
Was ich mit „gültig“ in meinem Fall bedeutet richtig gebildet XML ist. Ich habe nicht zu validieren Ressourcen oder Schema benötigen.

War es hilfreich?

Lösung

Es ist nicht möglich, die Wohlgeformtheits- einer XML-Zeichenfolge zu validieren, ohne sie zu parsen. Und eine schnelle Benchmark zeigt, dass der schnellste Weg, um eine Zeichenfolge zu analysieren, um zu sehen, ob es gültig ist (tatsächlich der schnellste Weg, um die bestimmte Zeichenfolge zu analysieren ich als Testfall verwendet wird) ist mit einem 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();
    }

Auf meinem Rechner XmlReader ist fast doppelt so schnell wie eine der Alternativen. Das macht Sinn. Obwohl ich Reflector nicht verwendet habe, um zu überprüfen, wäre ich sehr überrascht, wenn XmlDocument, XDocument und XPathDocument unter der Haube nicht alle mit XmlReader ist.

Andere Tipps

Ich bin mir nicht bewusst, eine eingebaute in der Einrichtung in .NET die gebildete-ness (?) Von XML zu validieren, ohne sie zu parsen. Da, so etwas wie dies funktionieren soll:

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

Vereinbaren Sie mit Adam und die XElement Version:

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;
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top