試してませんが、CygwinでもMinGWでも通用すると思います。
Expand
MSYSを、デフォルトの設定のままインストールしていると./autogen.shでこけます。
mingw-get-setup.exeを用意して、アップデートします。
その時、パッケージ選択で、All Packages -> MSYS -> MSYS System Builder を選択して、msys-autoconfとかmsys-automakeとかを一通りインストールします。
xz utils (liblzma)を利用するモジュールがあります。念のため準備しておきます。
http://www.gaia-gis.it/gaia-sins/mingw_how_to.html#liblzma
からxzのtarballを落としてきて、msysの自分のhomeディレクトリで解凍。
cd xz-5.2.2 ./configure --with-libiconv-prefix=/usr/local --with-libintl-prefix=/usr/local make
.libs/liblzma_la-stream_encoder_mt.o: In function `stream_encode_mt': xz-5.2.2/src/liblzma/../../src/common/mythread.h:389: undefined reference to `__beginthreadex'
beginthreadexはMSのCランタイムのやつらしいです。
liblzmaのgithubを確認、INSTALL-Windows.txtによるとwindows/build.bashを使えとのことですが、やってみても解消されず。
hostを指定してやれば大丈夫でした。設定を変えて再びビルド。
./configure --with-libiconv-prefix=/usr/local --with-libintl-prefix=/usr/local --host=i686-w64-mingw32 --prefix=/usr/local make make install-strip
prefixはこれでやるとパスが通ったところにインストールされるはずです。ですが次の節でも触れますが、間違いかもしれません。
ソースコードを入手gnomeのgitリポジトリから入手してきます。
--hostオプションはzlibが有効になるおまじない。
git clone git://git.gnome.org/libxml2 cd libxml2 autoupdate ./autogen.sh --with-lzma=no --host=i686-w64-mingw32
なんかconfigureの文法エラー。次のように変更しました。
12389行目からの3行をコメントアウトしました。
# PKG_CHECK_MODULES(LZMA,liblzma, # have_liblzma=yes, # have_liblzma=no)
15248行目位の_au_m4_changequoteを削りました。
#_au_m4_changequote(,)cat confdefs.h - conftest.$ac_ext cat confdefs.h - conftest.$ac_ext
autogen.shを使うとまたconfigureが上書きされるので、configureを直接たたきます。
./configure --with-python=no --host=i686-w64-mingw32 make make install
ところでconfigure中でlzmaの項目がnoになっているんですが、大丈夫なんでしょうか。 せっかくビルドしたのに。
これで/usr/local (WindowsのファイルシステムだとPath\to\msys\1.0\local)にlibxml2に関するいろいろがコピーされます。
https://sites.google.com/site/cobproducts/home/programmingsamples/xmlreader-1
http://xmlsoft.org/examples/index.html
http://xmlsoft.org/examples/index.html#reader1.c
http://xmlsoft.org/examples/reader1.c
<p> Are you an adult? br / br / <a href="http://yahoo.co.jp" target="_blank"> No </a>br / <a href="http://not-so-erotic-page"> Yes </a>br / <!-- True entrance:http://very-erotic-page--> </p>
brタグが括弧内に入っていませんが、< >を脳内保管してください。すみません。
brタグに/が入っているのは、xmlの書式に合わせるためです。 上の参考サイト(主にlibxml2公式のexampleコード)をもとに、これをパースするプログラムを作ります。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <libxml/xmlreader.h> static void processNode(xmlTextReaderPtr reader) { const xmlChar *name, *value; name = xmlTextReaderConstName(reader); if (name == NULL) name = BAD_CAST "--"; value = xmlTextReaderConstValue(reader); printf("%d %d %s %d %d", xmlTextReaderDepth(reader), xmlTextReaderNodeType(reader), name, xmlTextReaderIsEmptyElement(reader), xmlTextReaderHasValue(reader)); if (value == NULL) printf("\n"); else { if (xmlStrlen(value) > 40) printf(" %.40s...\n", value); else printf(" %s\n", value); } } static void streamFile(const char *filename) { xmlTextReaderPtr reader; int ret; reader = xmlReaderForFile(filename, NULL, 0); if (reader != NULL) { ret = xmlTextReaderRead(reader); while (ret == 1) { processNode(reader); ret = xmlTextReaderRead(reader); } xmlFreeTextReader(reader); if (ret != 0) { printf("%s : failed to parse\n", filename); } } else { printf("Unable to open %s\n", filename); } } int main(void){ LIBXML_TEST_VERSION streamFile("test.xml"); xmlCleanupParser(); xmlMemoryDump(); return 0; }
$ gcc read_xml.c -I/usr/local/include/libxml2 -I/D/MinGW/include/ -L/usr/local/lib -lxml2 $ ./a.exe
-I/D/MinGW/include/はiconv.hのため。
http://nantonaku-shiawase.hatenablog.com/entry/2012/04/30/231235
test.htmlを用意しますが、実験のためbrタグに/を取ったり残したりします。
<p> Are you an adult?br br <a href="http://yahoo.co.jp" target="_blank"> No </a>br <a href="http://not-so-erotic-page"> Yes </a>br / <!-- True entrance:http://very-erotic-page--> </p>
ここでもbrタグに< >を脳内保管してください。すみません。
次のようなプログラムを用意します。 read_html.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <libxml/HTMLparser.h> void FindInfo(xmlNode* element, int indent_len) { // elementノードのタイプと名前、コンテンツを表示 // indent_len だけ表示の行頭を下げて階層を分かりやすく char indent[indent_len + 1]; sprintf(indent, "% *s", indent_len, " "); // indent_len文字の空白文字列を作成 printf("%sElement name: %s, type: %d\n", indent, element->name, element->type); if(element->content != NULL){ printf("%sElement content: %s\n", indent, element->content); } if(element->properties != NULL){ // プロパティ(attribute)を持っていたらスキャン xmlAttrPtr attr; printf("%sElement attributes: \n", indent); for (attr = element->properties; attr != NULL; attr = attr->next) { printf("%s - Attribute name: %s, type: %d\n", indent, attr->name, attr->type); printf("%s - Attribute content: %s\n", indent, attr->children->content); } } if(element->children != NULL){ // 子ノードをスキャン、再帰的に呼び出し htmlNodePtr node; printf("%sElement childs: \n", indent); for (node = element->children; node != NULL; node = node->next) { FindInfo(node, indent_len + 3); } } } int main(void){ LIBXML_TEST_VERSION htmlDocPtr ptr; ptr = htmlReadFile("test.html", "utf-8", HTML_PARSE_RECOVER + HTML_PARSE_NOBLANKS + HTML_PARSE_NOIMPLIED + HTML_PARSE_COMPACT); if(ptr == NULL){return 1;} htmlNodePtr root = xmlDocGetRootElement(ptr); if(root != NULL){ FindInfo(root, 0); } /* 後片付け */ xmlFreeDoc(ptr); xmlCleanupParser(); xmlCleanupCharEncodingHandlers(); xmlMemoryDump(); return 0; }
$ gcc read_xml.c -I/usr/local/include/libxml2 -I/D/MinGW/include/ -L/usr/local/lib -lxml2 $ ./a.exe
Element name: p, type: 1 Element childs: Element name: text, type: 3 Element content: Are you an adult? Element name: br, type: 1 Element name: br, type: 1 Element name: a, type: 1 Element attributes: - Attribute name: href, type: 2 - Attribute content: http://yahoo.co.jp - Attribute name: target, type: 2 - Attribute content: _blank Element childs: Element name: text, type: 3 Element content: No Element name: br, type: 1 Element name: a, type: 1 Element attributes: - Attribute name: href, type: 2 - Attribute content: http://not-so-erotic-page Element childs: Element name: text, type: 3 Element content: Yes Element name: br, type: 1 Element name: comment, type: 8 Element content: True entrance:http://very-erotic-page
5行目のAre you an adult?が単独の行を持っていますが、これはpタグのすぐ後ろの改行文字が含まれているためです。 htmlReadFileのオプションのうち、NO_BLANKSがないと、brタグとaタグの前後の改行だけのテキストノードなどが出来て無駄なノードが多くなります。 NOIMPLIEDがあると勝手に頭にhtmlとbodyノードを付けます。
http://www.xmlsoft.org/html/libxml-tree.html#xmlElementType
例に挙げたtest.htmlは次の図のようにノード分けされたようです。