代码之家  ›  专栏  ›  技术社区  ›  JohnyL

无法将HTML分配给htmldocument.body

  •  1
  • JohnyL  · 技术社区  · 7 年前

    我想用 HTMLDocument 对象从 mshtml 图书馆。我试图将HTML分配给文档:

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

    但是,第三行出现错误:

    System.NullReferenceException:'对象引用未设置为 对象的实例。
    mshtml.disphtmldocument.body.get返回空值。

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

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

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

    Microsoft.CSharp.RuntimeBinder.RuntimeBinderException(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
    '无法对空引用执行运行时绑定'

    有什么办法可以克服这个问题吗?谢谢!

    更新: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
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Jimi    7 年前

    你可以把 mshtml.HtmlDocument 到 IHTMLDocument2 接口,使主要对象的属性和方法可用:

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

    或创建一个 HtmlDocumentClass 实例使用 Activator.CreateInstance() 使用类型guid,然后强制转换为 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 到 IHTMLDocument8 (从现在起),代替系统版本。

    经典 getElementById , getElementsByName , getElementsByTagName 方法在 IHTML文档3 接口。

    例如,使用 getElementsByTagName() 检索 InnerText 一个 HTMLElement 使用它的标签名:

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

    注释 :
    如果你找不到 IHTMLDocument6 , IHTMLDocument7 和 IHTML文档8 接口(以及可能在msdn文档中引用的其他接口),那么您可能在 \Windows\Assembly\ GAC . 按照Hans Passant的建议创建新的 Interop.mshtml 图书馆:
    How to get mshtml.IHTMLDocument6 or mshtml.IHTMLDocument7?

    推荐文章