Невозможно назначить HTML для HTMLDocument.body - PullRequest
0 голосов
/ 27 января 2019

Я хотел использовать 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:
'Невозможно выполнить привязку во время выполнения для пустой ссылки'

IsЕсть какое-то решение для преодоления этой проблемы?Спасибо!

ОБНОВЛЕНИЕ: код 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 голосов
/ 27 января 2019

Вы можете привести mshtml.HtmlDocument к интерфейсу IHTMLDocument2 , чтобы были доступны свойства и методы основных объектов:

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

Или создатьHtmlDocumentClass экземпляр с использованием Activator.CreateInstance() с Type Guid, затем приведение к интерфейсу IHTMLDocument2.

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

Это более или менее одно и то же.Я бы предпочел первый, в основном по этой причине

Тогда вы можете написать в 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 методы доступны в IHTMLDocument3 interface.

Например, используйте getElementsByTagName(), чтобы извлечь InnerText из HTMLElement, используя его имя тега:

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

Примечание :
Если вы не можете найти IHTMLDocument6, IHTMLDocument7 и IHTMLDocument8 интерфейсы (и, возможно, другие интерфейсы, на которые есть ссылки в Документах MSDN), тогда вы, вероятно, имеете старую библиотеку типов в \Windows\Assembly\ GAC.Следуйте советам Ханса Пассанта для создания новой библиотеки Interop.mshtml:
Как получить mshtml.IHTMLDocument6 или mshtml.IHTMLDocument7?

...