Domanda

Potrebbe sembrare una semplice domanda.

Ma ho cercato un parser XML da utilizzare in una delle mie applicazioni in esecuzione su Linux.

Sto usando Expat e ho analizzato il mio file XML leggendo uno in. Tuttavia, l'output è uguale all'input.

Questo è il mio file in cui sto leggendo:

<?xml version="1.0" encoding="utf-8"?>
    <books>
         <book>
              <id>1</id>
              <name>Hello, world!</name>
         </book>
    </books>

Tuttavia, dopo che ho superato questo, ottengo esattamente lo stesso dell'output. Mi chiedo a cosa serva il parser?

Solo un'altra cosa. Sto usando Expat. Che sembra abbastanza difficile da usare. Il mio codice è qui sotto: si legge in un file. Ma la mia applicazione dovrà analizzare un buffer che verrà ricevuto da un socket e non da un file. C'è qualche esempio di ciò che qualcuno ha?

int parse_xml(char *buff)
{
    FILE *fp;
    fp = fopen("mybook.xml", "r");
    if(fp == NULL)
    {
        printf("Failed to open file\n");
        return 1;
    }

   /* Obtain the file size. */
    fseek (fp, 0, SEEK_END);
    size_t file_size = ftell(fp);
    rewind(fp);

    XML_Parser parser = XML_ParserCreate(NULL);
    int done;
    memset(buff, 0, sizeof(buff));

    do
    {
        size_t len = fread(buff, 1, file_size, fp);
        done = len < sizeof(buff);

        if(XML_Parse(parser, buff, len, done) == XML_STATUS_ERROR)
        {
            printf("%s at line %d\n", XML_ErrorString(XML_GetErrorCode(parser)),
                                      XML_GetCurrentLineNumber(parser));
            return 1;
        }
    }
    while(!done);

    fclose(fp);
    XML_ParserFree(parser);

    return 0;
}
È stato utile?

Soluzione

Ci è voluto un po 'per avvolgere la mia testa intorno all'analisi XML (anche se lo faccio in Perl, non in C). Fondamentalmente, si registrano le funzioni di richiamata. Il parser eseguirà il ping del callback per ciascun nodo e passerà in una struttura di dati contenente tutti i tipi di bit succosi (come testo normale, eventuali attributi, nodi figlio, ecc.). Devi mantenere un qualche tipo di informazione sullo stato - come un albero di hash in cui colleghi elementi o una stringa che contiene tutte le viscere, ma nessuna dell'XML.

Ricorda solo che XML non è lineare e non ha molto senso analizzarlo come un lungo pezzo di testo. Invece, lo analizzi come un albero. Buona fortuna.

Altri suggerimenti

Expat è un parser guidato anche. Devi scrivere codice per gestire tag, attributi ecc. E quindi registrare il codice con il parser. C'è un articolo qui che descrive come fare questo.

Per quanto riguarda la lettura da un socket, a seconda della tua piattaforma potresti essere in grado di trattare il socket come un handle di file. Altrimenti, devi fare la tua lettura dal socket e quindi passare i dati per espatriare esplicitamente. C'è un'API per farlo. Tuttavia, proverei prima a farlo funzionare con i file ordinari.

Invece di expat, potresti voler dare un'occhiata a libxml2, che probabilmente è già incluso nella tua distribuzione. È molto più potente di expat e ti offre ogni sorta di chicche: DOM (modalità albero), SAX (modalità streaming), XPath (indispensabile per fare qualcosa di complesso con XML IMHO) e altro ancora. Non è leggero come gli espatriati, ma è molto più facile da usare.

Bene, hai scelto il parser XML più complicato (i parser guidati da eventi sono più difficili da gestire). Perché espatriare e non libxml ?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top