C#中利用Markup Service實現HTML解析為DOM Tree
2024-08-26 00:15:32
供稿:網友
一個輕量級parsing 實現。這個代碼不會從網上下載任何資料,也不會執行任何腳本,純屬parsing。
parsing是通過mshtml的markup service實現的。要正確使用這個代碼,需要添加mshtml引用。
由于.net中沒有定義ipersiststreamint接口,就必須自己實現,接口定義:
以下內容為程序代碼:
[comvisible(true), comimport(), guid("7fd52380-4e07-101b-ae2d-08002b2ec713 " ) , interfacetypeattribute(cominterfacetype.interfaceisiunknown)]
public interface ipersiststreaminit
{
void getclassid([in, out] ref guid pclassid);
[return: marshalas(unmanagedtype.i4)] [preservesig]
int isdirty();
void load([in, marshalas(unmanagedtype.interface)] ucomistream pstm);
void save([in, marshalas(unmanagedtype.interface)] ucomistream pstm,
[in, marshalas(unmanagedtype.i4)] int fcleardirty);
void getsizemax([out, marshalas(unmanagedtype.lparray)] long pcbsize);
void initnew();
}
以下內容為程序代碼:
unsafe ihtmldocument2 parse(string s)
{
ihtmldocument2 pdocument=new htmldocumentclass();
if(pdocument!=null)
{
ipersiststreaminit ppersist=pdocument as ipersiststreaminit ;
ppersist.initnew();
ppersist=null;
imarkupservices ms=pdocument as imarkupservices ;
if(ms!=null)
{
imarkupcontainer pmc=null;
imarkuppointer pstart,pend;
ms.createmarkuppointer(out pstart);
ms.createmarkuppointer(out pend);
stringbuilder sb=new stringbuilder(s);
intptr psource=marshal.stringtohglobaluni(s);
ms.parsestring(ref *(ushort*)psource.topointer(),0,out pmc,pstart,pend);
if(pmc!=null)
{
marshal.release(psource);
return pmc as ihtmldocument2;
}
marshal.release(psource);
}
}
return null;
}
寫代碼的時候出了一點問題,imarkupservice::parsestring第一個參數是ref ushort,顯然要傳入html代碼,這個ushort必須是第一個widechar了,所以這里通過使用不安全代碼來繞過編譯器警告。