web-dev-qa-db-fra.com

Analyseur XML pour C

Pouvez-vous suggérer certains des meilleurs analyseurs XML pour C?

45
coder

Deux des analyseurs les plus utilisés sont Expat et libxml .

Si vous êtes d'accord avec C++, il y a aussi Xerces-C++ .

38
Chris Jester-Young

Deux exemples avec expat et libxml2 . Le deuxième est, à mon humble avis, beaucoup plus facile à utiliser car il crée un arbre en mémoire, une structure de données avec laquelle il est facile de travailler. expat, d'autre part, ne construit rien (vous devez le faire vous-même), il vous permet simplement d'appeler des gestionnaires lors d'événements spécifiques pendant l'analyse. Mais l'expat peut être plus rapide (je n'ai pas mesuré).

Avec expat, lecture d'un fichier XML et affichage des éléments en retrait:

/* 
   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);
}

Avec libxml2, un programme qui affiche le nom de l'élément racine et les noms de ses enfants:

/*
   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;
}
66
bortzmeyer

Que diriez-vous d'un écrit en assembleur pur :-) N'oubliez pas de vérifier le benchmarks .

39
codelogic

Vous pouvez essayer ezxml - c'est un analyseur léger écrit entièrement en C.

Pour C++, vous pouvez consulter TinyXML ++

9
Kasprzol

http://www.minixml.org est également assez bon. Petit et juste ANSI C.

6
singpolyma

Ma préférence personnelle est libxml2 . Il est très facile à utiliser, mais je n'ai jamais pris la peine de le comparer, car je ne l'ai utilisé que pour l'analyse de fichiers de configuration.

4
Michael Foukarakis

Expat est assez décent. Il est difficile de donner de bonnes recommandations sans plus d'informations cependant.

2
Hank

Pourriez-vous donner une indication des plates-formes pour lesquelles vous écrivez? Cela devrait peser lourdement sur ce qui est "le meilleur". Vous pouvez trouver une bibliothèque super 'xml-foo' qui n'est pas livrée couramment sur la plupart des systèmes par défaut .. alors que c'est génial, le manque de bibliothèque peut empêcher (ou au moins) ennuyer les utilisateurs.

Surtout, j'utilise libxml2 .. car son standard ou facile à installer sur les plateformes que je cible.

Comme vous le voyez, le "meilleur" est également déterminé par la disponibilité de la bibliothèque sur vos plateformes cibles.

2
Tim Post

Pour C++, je suggère d'utiliser CMarkup .

2
Zhang Zhiliang

Sous Windows, il est natif avec l'API Win32 ...

0
terry