无法将 HTML 分配给 HTMLDocument.body

Can't assign HTML to HTMLDocument.body

我想使用 mshtml 库中的 HTMLDocument 对象。我试图将 HTML 分配给文档:

var doc = new mshtml.HTMLDocument();
var html = File.ReadAllText(@"path_to_html_file");
doc.body.innerHTML = html; // <-- this line throws error

但是,我在第三行出现错误:

System.NullReferenceException: 'Object reference not set to an instance of an object.'
mshtml.DispHTMLDocument.body.get returned null.

我尝试使用动态代码,但它也不起作用:

dynamic doc = Activator.CreateInstance(Type.GetTypeFromProgID("htmlfile"));

在这种情况下,我得到以下错误:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
'Cannot perform runtime binding on a null reference'

有什么办法可以解决这个问题吗?谢谢!

更新:VBA代码

Sub GetData()
    Dim doc As MSHTML.HTMLDocument
    Dim fso As FileSystemObject, txt As TextStream

    Set doc = New MSHTML.HTMLDocument
    Set fso = New FileSystemObject
    Set txt = fso.OpenTextFile("path_to_html_file")
    doc.body.innerHTML = txt.ReadAll() '// <-- No error here
    txt.Close
End Sub

您可以将 mshtml.HtmlDocument 转换为 IHTMLDocument2 接口,以获得主要对象的属性和方法:

var doc = (IHTMLDocument2)new mshtml.HTMLDocument();

或者使用 Activator.CreateInstance() 和 Type Guid 创建一个 HtmlDocumentClass 实例,然后转换为 IHTMLDocument2 接口。

IHTMLDocument2 doc = 
   (IHTMLDocument2)Activator.CreateInstance(
       Type.GetTypeFromCLSID(new Guid("25336920-03F9-11CF-8FD0-00AA00686F13")));

大同小异。我更喜欢第一个,主要是 for this reason

然后你可以向HtmlDocument写任何你想写的东西。例如:

doc.write(File.ReadAllText(@"[Some Html Page]"));
Console.WriteLine(doc.body.innerText);

要创建 HtmlDocument,骨架 HTML 页面就足够了,像这样:

string html = "<!DOCTYPE html><html><head></head><Body><p></body></html>";
doc.write(html);

注意:在创建文档之前,页面中的所有元素都将是null

之后,您可以将 Body.InnerHtml 设置为其他值:

doc.body.innerHTML = "<P>Some Text</P>";
Console.WriteLine(doc.body.innerText);

请注意,如果您需要更广泛地使用 HTML 文档,则必须转换到更高级别的接口:IHTMLDocument3 to IHTMLDocument8(截至目前),具体取决于系统版本.

经典的 getElementById, getElementsByName, getElementsByTagName 方法在 IHTMLDocument3 界面中可用。

例如,使用 getElementsByTagName() 检索 HTMLElementInnerText使用它的标签名称:

string innerText = 
   (doc as IHTMLDocument3).getElementsByTagName("body")
                          .OfType<IHTMLElement>().First().inne‌​rText;

:
如果找不到 IHTMLDocument6IHTMLDocument7IHTMLDocument8 接口(可能还有 MSDN 文档中引用的其他接口),那么您可能在 \Windows\Assembly\ GAC 中有一个旧类型库。按照 Hans Passant 的建议创建一个新的 Interop.mshtml 库:

我也遇到了 System.NullReferenceException,因为 doc.body 是空的。最后我是这样解决问题的:

   public void SetWebBrowserHtml(WebBrowser webBrowser, string html)
    {
        if (!(webBrowser.Document is MSHTML.IHTMLDocument2))
        {
            webBrowser.Navigate("about:blank");
        }
        if (webBrowser.Document is MSHTML.IHTMLDocument2 doc)
        {
            if (doc.body == null)
            {
                doc.write(html);
            }
            else
            {
                doc.body.innerHTML = html;
            }
        }
    }