libxml2でHTMLを整形する
だいぶ前にlibxml2を使ってHTMLをパースした。
libxmlでHTMLParserを使う - なんとな~くしあわせ?の日記
libxml2のAPIを見ていると、HTMLの整形も出来るらしいのでやってみた。
使用したAPI
htmlDocContentDumpFormatOutput
http://xmlsoft.org/html/libxml-HTMLtree.html#htmlDocContentDumpFormatOutput
void htmlDocContentDumpFormatOutput (xmlOutputBufferPtr buf, xmlDocPtr cur, const char * encoding, int format)
Dump an HTML document. HTMLの文書を出力する buf: the HTML buffer output cur: the document encoding: the encoding string format: should formatting spaces been added
htmlReadMemory
http://xmlsoft.org/html/libxml-HTMLparser.html#htmlReadMemory
htmlDocPtr htmlReadMemory (const char * buffer, int size, const char * URL, const char * encoding, int options)
parse an XML in-memory document and build a tree. XMLをメモリ上でパースしてHTMLのリストを構築する buffer: a pointer to a char array size: the size of the array URL: the base URL to use for the document encoding: the document encoding, or NULL options: a combination of htmlParserOption(s) Returns: the resulting document tree
xmlOutputBufferCreateIO
http://xmlsoft.org/html/libxml-xmlIO.html#xmlOutputBufferCreateIO
xmlOutputBufferPtr xmlOutputBufferCreateIO (xmlOutputWriteCallback iowrite,
xmlOutputCloseCallback ioclose,
void * ioctx,
xmlCharEncodingHandlerPtr encoder)
Create a buffered output for the progressive saving to an I/O handler 入出力ハンドラを漸進的に保存するためのバッファされた出力を作る (うまく訳せないけど一方で読み込んで一方で書き出す入出力ストリームを作る) iowrite: an I/O write function ioclose: an I/O close function ioctx: an I/O handler encoder: the charset encoding if known Returns: the new parser output or NULL
サンプルコード
難しいのはxmlOutputBufferPtrの構築。
この構造体はコールバックとして書き出しとクローズの関数を持っている。コールバックがどのように文字列を書き出すか設定してやる必要がある。あとはAPIにしたがって関数を使うだけだ。
static int writeToWxString(void* context, const char* buffer, int len) { wxString* t = static_cast<wxString*>(context); *t += wxString(buffer, wxConvUTF8, len); return len; } static void closeWxString(void* context) { wxString* t = static_cast<wxString*>(context); *t += wxString::FromAscii("\n"); } /** * HTML整形 */ const wxString HtmlFormat(const wxString& html) { htmlDocPtr docPtr = htmlReadMemory(html.mb_str(), html.Len(), "", "utf-8", HTML_PARSE_RECOVER); if (docPtr) { // libxml2の***Ptrは何かの構造体のポインタ wxString val; xmlOutputBufferPtr buf = xmlOutputBufferCreateIO((xmlOutputWriteCallback)writeToWxString, (xmlOutputCloseCallback)closeWxString, &val, 0); htmlDocContentDumpOutput(buf, docPtr, "utf-8"); return val; } }