我有一个继承的遗留应用程序,它将大量 XML 作为字符串传递。
我经常需要能够检查字符串是否是有效的 XML。在 .NET 中检查字符串是否为有效 XML 的最快和最便宜的方法是什么?
我在 .NET 3.5 中工作,很可能在解决方案中的这个项目中将其用作扩展方法(脱离字符串)。
更新:
在我的情况下,我所说的“有效”是正确格式的 XML。我不需要验证资源或架构。
我有一个继承的遗留应用程序,它将大量 XML 作为字符串传递。
我经常需要能够检查字符串是否是有效的 XML。在 .NET 中检查字符串是否为有效 XML 的最快和最便宜的方法是什么?
我在 .NET 3.5 中工作,很可能在解决方案中的这个项目中将其用作扩展方法(脱离字符串)。
更新:
在我的情况下,我所说的“有效”是正确格式的 XML。我不需要验证资源或架构。
我不知道 .NET 中有一个内置工具可以在不解析 XML 的情况下验证 XML 的形成性 (?)。鉴于此,这样的事情应该有效:
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;
}
}
}
同意 Adam 和 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;
}
}
}
如果不解析 XML 字符串,就无法验证其格式是否正确。一个快速的基准测试表明,解析字符串以查看它是否有效的最快方法(实际上是解析我用作测试用例的特定字符串的最快方法)是使用 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();
}
在我的机器XmlReader
上几乎是任何替代品的两倍。这是有道理的。虽然我没有使用 Reflector 进行检查,但如果XmlDocument
, XDocument
, 和XPathDocument
并没有XmlReader
在后台使用,我会感到非常惊讶。