C向けの最高のXMLパーサーをいくつか提案できますか?
最も広く使用されているパーサーの2つは、 Expat と libxml です。
C++を使用しても問題ない場合は、 Xerces-C++ もあります。
expat および libxml2 の2つの例。 2つ目は、メモリ内にツリーを作成するため、使いやすいデータ構造であるIMHOです。一方、expatは何も構築しません(自分で行う必要があります)。解析中に特定のイベントでハンドラーを呼び出すことができます。しかし、expatはもっと速いかもしれません(私は測定しませんでした)。
Expatを使用して、XMLファイルを読み取り、インデントされた要素を表示します。
/*
A simple test program to parse XML documents with expat
<http://expat.sourceforge.net/>. It just displays the element
names.
On Debian, compile with:
gcc -Wall -o expat-test -lexpat expat-test.c
Inspired from <http://www.xml.com/pub/a/1999/09/expat/index.html>
*/
#include <expat.h>
#include <stdio.h>
#include <string.h>
/* Keep track of the current level in the XML tree */
int Depth;
#define MAXCHARS 1000000
void
start(void *data, const char *el, const char **attr)
{
int i;
for (i = 0; i < Depth; i++)
printf(" ");
printf("%s", el);
for (i = 0; attr[i]; i += 2) {
printf(" %s='%s'", attr[i], attr[i + 1]);
}
printf("\n");
Depth++;
} /* End of start handler */
void
end(void *data, const char *el)
{
Depth--;
} /* End of end handler */
int
main(int argc, char **argv)
{
char *filename;
FILE *f;
size_t size;
char *xmltext;
XML_Parser parser;
if (argc != 2) {
fprintf(stderr, "Usage: %s filename\n", argv[0]);
return (1);
}
filename = argv[1];
parser = XML_ParserCreate(NULL);
if (parser == NULL) {
fprintf(stderr, "Parser not created\n");
return (1);
}
/* Tell expat to use functions start() and end() each times it encounters
* the start or end of an element. */
XML_SetElementHandler(parser, start, end);
f = fopen(filename, "r");
xmltext = malloc(MAXCHARS);
/* Slurp the XML file in the buffer xmltext */
size = fread(xmltext, sizeof(char), MAXCHARS, f);
if (XML_Parse(parser, xmltext, strlen(xmltext), XML_TRUE) ==
XML_STATUS_ERROR) {
fprintf(stderr,
"Cannot parse %s, file may be too large or not well-formed XML\n",
filename);
return (1);
}
fclose(f);
XML_ParserFree(parser);
fprintf(stdout, "Successfully parsed %i characters in file %s\n", size,
filename);
return (0);
}
Libxml2では、ルート要素の名前とその子の名前を表示するプログラム:
/*
Simple test with libxml2 <http://xmlsoft.org>. It displays the name
of the root element and the names of all its children (not
descendents, just children).
On Debian, compiles with:
gcc -Wall -o read-xml2 $(xml2-config --cflags) $(xml2-config --libs) \
read-xml2.c
*/
#include <stdio.h>
#include <string.h>
#include <libxml/parser.h>
int
main(int argc, char **argv)
{
xmlDoc *document;
xmlNode *root, *first_child, *node;
char *filename;
if (argc < 2) {
fprintf(stderr, "Usage: %s filename.xml\n", argv[0]);
return 1;
}
filename = argv[1];
document = xmlReadFile(filename, NULL, 0);
root = xmlDocGetRootElement(document);
fprintf(stdout, "Root is <%s> (%i)\n", root->name, root->type);
first_child = root->children;
for (node = first_child; node; node = node->next) {
fprintf(stdout, "\t Child is <%s> (%i)\n", node->name, node->type);
}
fprintf(stdout, "...\n");
return 0;
}
ezxml を試すことができます-これは完全にCで書かれた軽量のパーサーです。
C++の場合、チェックアウトできます TinyXML ++
http://www.minixml.org もかなり良いです。小さくてちょうどANSI C.
私の個人的な好みは libxml2 です。使い方は非常に簡単ですが、構成ファイルの解析にしか使用していないため、気にしませんでした。
Expat はかなりまともです。ただし、詳細な情報なしに適切な推奨事項を提示することは困難です。
どのプラットフォーム向けに書いているのか教えていただけますか?これは、「最良」であるものに重くのしかかるべきです。デフォルトではほとんどのシステムで一般的に出荷されないスーパー「xml-foo」ライブラリを見つけることができます..その素晴らしい一方で、ライブラリの欠如はユーザーを(少なくとも)悩ませるかもしれません。
ほとんどの場合、libxml2 ..を使用しています。これは、ターゲットとするプラットフォームに標準または簡単にインストールできるためです。
ご覧のとおり、「最適」は、ターゲットプラットフォームで利用可能なライブラリによっても決まります。
C++の場合、 CMarkup を使用することをお勧めします。
Windowsでは、Win32 APIがネイティブです...