17

Does anyone know of a quick way to check if a string is parseable as XML in C#? Preferably something quick, low resource, which returns a boolean whether or not it will parse.

I'm working on a database app which deals with errors that are sometimes stored as XML, and sometimes not. Hence, I'd like to just be able to test the string I grab from the database (contained in a DataTable) very quickly...and not have to resort to any try / catch {} statements or other kludges...unless those are the only way to make it happen.

4

4 回答 4

17

听起来您有时会返回 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 开头<但不是有效 XML 的消息时。

于 2013-09-09T18:46:43.313 回答
13

您可以尝试将字符串解析为 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()) {

于 2013-09-09T18:35:40.647 回答
6

你能真正找出某些东西是否会真正解析的唯一方法是……尝试解析它。

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

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

虽然我相信 encoding 属性是可选的(默认为 UTF-8。它也可能有一个standalone值为yesor的属性no。如果存在,这是一个很好的指标,表明文档应该是有效的 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 ;
}
于 2013-09-16T23:11:12.393 回答
0

我所知道的测试格式良好的 XML 的最佳答案是在 C# 中以编程方式检查 XML 文件的格式良好的最快方法是什么? xml 文件的形成性”它涵盖了使用 XMLReader 有效地执行此操作。

于 2013-09-09T18:44:17.400 回答