2009-03-04 15 views
0

Das mag wie eine einfache Frage erscheinen.Was ist ein XML-Parser? Using Expat

Aber ich habe nach einem XML-Parser gesucht, um in einer meiner Anwendungen zu verwenden, die unter Linux ausgeführt wird.

Ich benutze Expat und habe meine XML-Datei durch Lesen von einem in geparst. Die Ausgabe ist jedoch die gleiche wie die Eingabe.

Dies ist meine Datei, die ich beim Lesen bin:

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

Doch nachdem ich diese bestanden haben, bekomme ich genau das gleiche wie der Ausgang. Es lässt mich fragen, wofür der Parser ist?

Nur noch eine Sache. Ich verwende Expat. Das scheint ziemlich schwierig zu sein. Mein Code ist unten: Dies liest eine Datei ein. Aber meine Anwendung muss einen Puffer analysieren, der von einem Socket und nicht von einer Datei empfangen wird. Gibt es Proben davon, die jemand hat?

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; 
} 

Antwort

2

Es hat eine Weile gedauert, bis ich mich mit dem XML-Parsing beschäftigt habe (obwohl ich es in Perl und nicht in C mache). Grundsätzlich registrieren Sie Callback-Funktionen. Der Parser pingt Ihren Callback für jeden Knoten an und übergibt eine Datenstruktur, die alle Arten von saftigen Bits enthält (wie Klartext, beliebige Attribute, untergeordnete Knoten usw.). Sie müssen eine Art von Statusinformationen pflegen - wie eine Hash-Struktur, in die Sie Objekte stecken, oder eine Zeichenfolge, die alle Eingeweide enthält, aber keines der XML.

Denken Sie daran, dass XML nicht linear ist und es nicht viel Sinn macht, es wie ein langes Stück Text zu analysieren. Stattdessen parst du es wie einen Baum. Viel Glück.

3

Expat ist ein even-driven Parser. Sie müssen Code schreiben, um mit Tags, Attributen usw. umzugehen, und dann den Code beim Parser registrieren. Es gibt einen Artikel here, der beschreibt, wie dies zu tun ist.

In Bezug auf das Lesen von einem Socket, abhängig von Ihrer Plattform können Sie in der Lage sein, den Sockel wie ein Datei-Handle zu behandeln. Andernfalls müssen Sie Ihre eigenen Lesevorgänge vom Socket ausführen und die Daten dann explizit an Expat übergeben. Dazu gibt es eine API. Ich würde jedoch versuchen, es zuerst mit normalen Dateien arbeiten zu lassen.

2

Statt expat sollten Sie sich libxml2 ansehen, die wahrscheinlich bereits in Ihrer Distribution enthalten ist. Es ist viel mächtiger als Expat, und gibt Ihnen alle Arten von Leckereien: DOM (Baum-Modus), SAX (Streaming-Modus), XPath (unverzichtbar, etwas komplexes mit XML IMHO) und vieles mehr. Es ist nicht so leicht wie Expat, aber es ist viel einfacher zu bedienen.

0

Nun, Sie haben den kompliziertesten XML-Parser gewählt (ereignisgesteuerte Parser sind schwieriger zu handhaben). Warum Expat und nicht libxml?