测试某些内容是否是 C# 中可解析的 XML

本文关键字:XML 是否是 测试 | 更新日期: 2023-09-27 18:30:39

有谁知道一种快速的方法来检查字符串是否可以在 C# 中解析为 XML?最好是快速、低资源的东西,无论它是否会解析,它都会返回一个布尔值。

我正在开发一个数据库应用程序,该应用程序处理有时存储为 XML 的错误,有时不存储。 因此,我希望能够非常快速地测试我从数据库中抓取的字符串(包含在数据表中)......并且不必诉诸任何尝试/捕获{}语句或其他笨拙...除非这些是实现这一目标的唯一途径。

测试某些内容是否是 C# 中可解析的 XML

听起来你有时会得到XML,有时你会得到"纯"(非XML)文本。

如果是这种情况,您可以检查文本是否以<开头:

if (!string.IsNullOrEmpty(str) && str.TrimStart().StartsWith("<"))
    var doc = XDocument.Parse(str);

由于"纯"消息似乎不太可能以<开头,因此这可能是合理的。 您唯一需要决定的是,在边缘情况下该怎么做,即您有以<开头的非 XML 文本?

如果是我,我会默认尝试解析它并捕获异常:

if (!string.IsNullOrEmpty(str) && str.TrimStart().StartsWith("<"))
{
    try
    {
        var doc = XDocument.Parse(str);
        return //???
    }   
    catch(Exception ex)
        return str;
}
else
{
    return str;   
}

这样,只有当您有一条以 < 开头但不是有效 XML 的消息时,您才会产生引发异常的开销。

您可以尝试将字符串解析为 XDocument。如果解析失败,那么您就知道它无效。

string xml = "";
XDocument document = XDocument.Parse(xml);

如果你不想让丑陋的 try/catch 可见,你可以把它扔到字符串类上的扩展方法中......

public static bool IsValidXml(this string xml)
{
    try
    {
        XDocument.Parse(xml);
        return true;
    }
    catch
    {
        return false;
    }
}

然后你的代码看起来就像 if (mystring.IsValidXml()) {

真正了解某些内容是否实际解析的唯一方法是...尝试解析它。

XMl 文档应该(但可能没有)在文件开头,在 BOM(如果存在)之后有一个 XML 声明。它应该看起来像这样:

<?xml version="1.0" encoding="UTF-8" ?>

尽管我相信编码属性是可选的(默认为 UTF-8。它还可能具有值为 yesnostandalone 属性。如果存在,则这是一个很好的指标,表明文档应该是有效的XML。

根据

@GaryWalker的出色答案,我认为这样的事情已经足够好了(尽管设置可能需要一些调整,也许是自定义的无操作解析器)。只是为了踢球,我使用 XMark xmlgen (http://www.xml-benchmark.org/) 生成了一个 300mb 的随机 XML 文件:用下面的代码验证它在我的台式机上需要 1.7-1.8 秒的时间。

public static bool IsMinimallyValidXml( Stream stream )
{
  XmlReaderSettings settings = new XmlReaderSettings
    {
      CheckCharacters              = true                          ,
      ConformanceLevel             = ConformanceLevel.Document     ,
      DtdProcessing                = DtdProcessing.Ignore          ,
      IgnoreComments               = true                          ,
      IgnoreProcessingInstructions = true                          ,
      IgnoreWhitespace             = true                          ,
      ValidationFlags              = XmlSchemaValidationFlags.None ,
      ValidationType               = ValidationType.None           ,
    } ;
  bool isValid ;
  using ( XmlReader xmlReader = XmlReader.Create( stream , settings ) )
  {
    try
    {
      while ( xmlReader.Read() )
      {
        ; // This space intentionally left blank
      }
      isValid = true ;
    }
    catch (XmlException)
    {
      isValid = false ;
    }
  }
  return isValid ;
}
static void Main( string[] args )
{
  string text = "<foo>This &SomeEntity; is about as simple as it gets.</foo>" ;
  Stream stream = new MemoryStream( Encoding.UTF8.GetBytes(text) ) ;
  bool isValid = IsMinimallyValidXml( stream ) ;
  return ;
}

对于测试我所知道的格式良好的 XML,我似乎最好的答案是 以编程方式检查 C# 中 XML 文件的格式良好的最快方法是什么?xml-file的形成性" 它涵盖了使用XMLReader来有效地做到这一点。