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