一個輕量級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了,所以這里通過使用不安全代碼來繞過編譯器警告。