Rendimiento Método de extensión .NET IsValidXml
-
25-09-2019 - |
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.
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;
}
}
}