トップC-Tips > 簡易XMLパーサー

簡易XMLパーサー[2013.02.16]

1.はじめに

現在のホームページは左フレームに全体の目次(toc.html)を置いている。 サイトマップや大項目別目次などはない。 少し使いやすくするために、大項目別目次(index.html)を最上位のサブディレクトリ上に置きたい。

目次は、htmlファイルを直接書くのではなく、 SQLiteデータベースの表またはXMLデータとして管理する。 同じ見出しを2箇所に置いたりするので、XMLデータとする方が扱いやすいと思われる。

本格的なXMLパーサーならば、現状では Javaとか C# の方が楽に作れる。 しかし、CSVファイルを一歩進めた程度で、 C言語で限定仕様のコンパクトなパーサーを作ることにする。

2.主なる仕様

基本構造例を下に示す。このようなテーブルの記述だけをパースする。 とりあえず、thタグは使用せず、tdタグのみとする。

typedef struct _Table {
    char *name;                 // テーブル名
    int  nRow;                  // 行数(列名行を含む)
    int  nCol;                  // 列数
    char *data[MAXROW][MAXCOL]; // データ
} Table;

3.プログラムソース

手作業で管理する元ファイルの構造を下に示す。 テーブルは3列としているが、最後の列はオプション用であり、現在は使っていない。 一行目の最初のデータが ID、次が index.html を置くディレクトリを表す。 二行目以降が個々のページを指すリンクである。最初の列が見出し、次がパスを表す。

例外として、ルートにおくリンクに対しては名前(caption)および管理情報をもつ行はない。

プログラムソースを下に示す。 tochead.txt と toc.xml から全体の目次toc.htmlおよび 章別index.htmlを生成する。 最初に toc.html ファイルの更新時刻と tochead.txtおよびtoc.xmlファイルの更新時刻を比較して、 更新がなければ、処理終了としている。

【改定来歴】

2013.4.6 toc.xmlサイズは32KB程度になっても、ファイルは1回で全データを読み込める。 しかし、終わりに近いところに ヌル文字が混入する。 そこで、次のように、複数回に分けて読み込むように変更した。

    offset = 0;
    do {   // 1回で読み込むとエラーが起きた
        int nBytes = fread(buf+offset, sizeof(char), 4096, fp);
        offset += nBytes;
    } while (!feof(fp));