无法将HTML分配给HTMLDocument.body

时间:2019-01-27 13:58:46

标签: c# .net mshtml

我想使用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返回null。

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

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

在这种情况下,出现以下错误:

  

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 个答案:

答案 0 :(得分:1)

您可以将 mshtml.HtmlDocument 投射到IHTMLDocument2界面,以使主要对象的属性和方法可用:

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

或使用带有类型向导的HtmlDocumentClass创建一个 Activator.CreateInstance() 实例,然后转换为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文档,则必须转换为更高级别的界面:IHTMLDocument3IHTMLDocument8(截至目前),具体取决于系统版本。

经典的getElementByIdgetElementsByNamegetElementsByTagName方法在 IHTMLDocument3 界面中可用。

例如,使用 getElementsByTagName() 来使用其标记名称检索 InnerText HTMLElement

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

注意
如果找不到 IHTMLDocument6 IHTMLDocument7 IHTMLDocument8 接口(可能还有其他接口) MSDN Docs中引用的接口),那么您可能在\Windows\Assembly\ GAC中拥有旧的Type库。按照Hans Passant的建议创建一个新的 Interop.mshtml 库:
How to get mshtml.IHTMLDocument6 or mshtml.IHTMLDocument7?