一个轻量级parsing实现。这个代码不会从网上下载任何资料,也不会执行任何脚本,纯属parsing。
parsing是通过mshtml的markupservice实现的。要正确使用这个代码,需要添加mshtml引用。
由于.net中没有定义ipersiststreamint接口,就必须自己实现,接口定义:
以下内容为程序代码:
[comvisible(true),comimport(),guid("7fd52380-4e07-101b-ae2d-08002b2ec713"),interfacetypeattribute(cominterfacetype.interfaceisiunknown)]
publicinterfaceipersiststreaminit
{
voidgetclassid([in,out]refguidpclassid);
[return:marshalas(unmanagedtype.i4)][preservesig]
intisdirty();
voidload([in,marshalas(unmanagedtype.interface)]ucomistreampstm);
voidsave([in,marshalas(unmanagedtype.interface)]ucomistreampstm,
[in,marshalas(unmanagedtype.i4)]intfcleardirty);
voidgetsizemax([out,marshalas(unmanagedtype.lparray)]longpcbsize);
voidinitnew();
}
以下内容为程序代码:
unsafeihtmldocument2parse(strings)
{
ihtmldocument2pdocument=newhtmldocumentclass();
if(pdocument!=null)
{
ipersiststreaminitppersist=pdocumentasipersiststreaminit;
ppersist.initnew();
ppersist=null;
imarkupservicesms=pdocumentasimarkupservices;
if(ms!=null)
{
imarkupcontainerpmc=null;
imarkuppointerpstart,pend;
ms.createmarkuppointer(outpstart);
ms.createmarkuppointer(outpend);
stringbuildersb=newstringbuilder(s);
intptrpsource=marshal.stringtohglobaluni(s);
ms.parsestring(ref*(ushort*)psource.topointer(),0,outpmc,pstart,pend);
if(pmc!=null)
{
marshal.release(psource);
returnpmcasihtmldocument2;
}
marshal.release(psource);
}
}
returnnull;
}
写代码的时候出了一点问题,imarkupservice::parsestring第一个参数是refushort,显然要传入html代码,这个ushort必须是第一个widechar了,所以这里通过使用不安全代码来绕过编译器警告。