XDocument.Load(XmlReader) 可能出现的异常情况

17

XDocument.Load(XmlReader)方法被调用时可能会引发哪些异常? 当文档未提供关键信息时,遵循最佳实践(例如避免使用通用的try catch块)可能会很困难。

感谢您的帮助。


1
可能有一些异常情况,您不想捕获吗?如果这是一个 UI,则异常(任何异常)意味着失败,您将无法加载文档,并且必须向用户显示错误消息。如果是更多的服务器端,那么再次,任何异常都意味着失败,您不太可能从中恢复,因此最好的方法是将其包装在另一个异常中,并为其提供一些上下文,以便它升级到全局异常处理程序。 - Kirk Woll
1
我不想捕获stackoverflow或OutOfMemory异常,例如。我想知道可以预期哪些异常,以便我可以在本地处理它们。其他任何异常都可以冒泡到我的全局异常处理程序进行日志记录。我知道有许多不同的异常处理思想。我是开发新手(总共8个月,只有2个月全职),所以我仍在处理所有这些。然而,无论遵循哪种学派,我认为希望可能的异常实际上被记录下来似乎是合理的。我们可能都会同意这一点。 - Joe DePung
4个回答

22

根据MSDN文档,LINQ to XML的加载功能是基于XmlReader构建的。因此,您可能会捕获到由XmlReader引发的任何异常。创建重载方法和读取和解析文档的XmlReader方法。

http://msdn.microsoft.com/en-us/library/756wd7zs.aspx ArgumentNullException和SecurityException

编辑:MSDN并不总是准确的。因此,我使用反编译器分析了Load方法代码,并得到了如下结果:

public static XDocument Load(XmlReader reader)
{
    return Load(reader, LoadOptions.None);
}

方法 Load 在调用以下方法:

public static XDocument Load(XmlReader reader, LoadOptions options)
{
    if (reader == null)
    {
        throw new ArgumentNullException("reader"); //ArgumentNullException
    }
    if (reader.ReadState == ReadState.Initial)
    {
        reader.Read();// Could throw XmlException according to MSDN
    }
    XDocument document = new XDocument();
    if ((options & LoadOptions.SetBaseUri) != LoadOptions.None)
    {
        string baseURI = reader.BaseURI;
        if ((baseURI != null) && (baseURI.Length != 0))
        {
            document.SetBaseUri(baseURI);
        }
    }
    if ((options & LoadOptions.SetLineInfo) != LoadOptions.None)
    {
        IXmlLineInfo info = reader as IXmlLineInfo;
        if ((info != null) && info.HasLineInfo())
        {
            document.SetLineInfo(info.LineNumber, info.LinePosition);
        }
    }
    if (reader.NodeType == XmlNodeType.XmlDeclaration)
    {
        document.Declaration = new XDeclaration(reader);
    }
    document.ReadContentFrom(reader, options); // InvalidOperationException
    if (!reader.EOF)
    {
        throw new InvalidOperationException(Res.GetString("InvalidOperation_ExpectedEndOfFile")); // InvalidOperationException
    }
    if (document.Root == null)
    {
        throw new InvalidOperationException(Res.GetString("InvalidOperation_MissingRoot")); // InvalidOperationException
    }
    return document;
}

有可能会出现异常的行已被注释掉。

我们可能会遇到以下异常:ArgumentNullException,XmlException和InvalidOperationException。MSDN说可能会出现SecurityException,但在创建XmlReader时也可能出现此类异常。


谢谢您的回复。不幸的是,我知道格式错误的 XML 也会引发其他错误(我有时也看到过这些错误)。 - Joe DePung
3
非常抱歉回答不正确!我使用反射分析了XDocument.Load(XmlReader)方法,并发现可能会出现两个异常InvalidOperationException和XmlException。MSDN并不总是说得准确。 - Nastya Kholodova
嘿,伙计!跟进得不错。我非常感激。我还没有探索过反射。那真的很有帮助。标记为答案。 - Joe DePung

3

XmlReader.Create(Stream) 可能会引发两种类型的异常:[src]

XmlReader reader; // Do whatever you want

try
{
  XDocument.Load(reader);
}
catch (ArgumentNullException)
{
  // The input value is null.
}
catch (SecurityException)
{
  // The XmlReader does not have sufficient permissions 
  // to access the location of the XML data.
}
catch (FileNotFoundException)
{
  // The underlying file of the path cannot be found
}

0

看起来在线文档没有说明抛出哪些异常...太糟糕了。使用FileInfo实例并调用它的Exists方法,以确保文件确实存在,这样您就不必捕获FileNotFoundException类型的异常,这样您就可以避免一些麻烦。

[编辑]

重新阅读您的帖子时,我忘记注意到您正在传递XML Reader。我的回答是基于传递代表文件的字符串(重载方法)。

鉴于此,我建议创建一个格式错误的XML测试文件并尝试加载它,以查看实际抛出的异常类型。然后处理这些情况。


除非有人能够为我提供一个列表,否则我认为这可能是我的唯一选择。虽然在文档中有一个列表会很好,但还是感谢您的建议。 - Joe DePung
使用File.Exists检查不是防止FileNotFoundException的明智方法,它只会创建竞争条件。保证文件存在的唯一可靠方法是实际尝试打开文件并捕获FileNotFoundException。 - Aaronaught
1
请阅读我的帖子。我从未建议使用File.Exists。我建议使用FileInfo实例。请不要在几个月后进来并扣除我的分数,因为您从一开始就没有对原始对话做出贡献。 - C.J.
Aaron,你从未解释过为什么它会创建竞争条件。证明的责任在你身上,而不是我。 - C.J.

0
我正在跟随一个关于使用XDocument在.NET 6中进行网页抓取的教程。然而,当我调用XDocument.Load("...")来加载一个.html页面时,我遇到了以下异常:
System.Xml.XmlException: ''src' is an unexpected token. The expected token is '='. Line 47, position 32.'

因此,根据您要解析的内容以及是否需要更宽松的解析方式,也许其他库更适合。我选择了IronWebScraper,它对我正在处理的HTML效果更好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接