Anzeige:
Ergebnis 1 bis 6 von 6

Thema: libxml2: xmlParseFile bricht mit "error : Interrupted function call" ab

  1. #1
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418

    libxml2: xmlParseFile bricht mit "error : Interrupted function call" ab

    Hallo,

    ich habe ein Problem mit libxml2 in Zusammenhang mit XMMS. Ich programmiere gerade an einem XMMS-Plugin, dazu muss ich eine XML-Datei auslesen (z.B. diese hier).
    Das funktioniert in meinem Einzelprogramm sehr gut (ich muss der libxml2 Funktion xmlParseFile() nur die URL übergeben, die holt sich dann das XML-Dokument selbstständig aus dem Netz).

    Wenn ich den Code jetzt in das XMMS-Plugin übertragen will, dann wird allerdings xmlParseFile immer unterbrochen und schreibt folgendes als Fehlermeldung auf das Terminal:
    Code:
    error : Interrupted function call
    I/O warning : failed to load external entity "http://musicbrainz.org/ws/1/track/?type=xml&artist=%54%68%65%20%46%69%65%72%79%20%46%75%72%6e%61%63%65%73&limit=1&title=%41%75%74%6f%6d%61%74%69%63%20%48%75%73%62%61%6e%64"
    .

    Kopiere ich diese URL (http://musicbrainz.org/ws/1/track/?t...73%62%61%6e%64) dann in mein Testprogramm, verrichtet xmlParseFile seinen Dienst ganz normal.

    So, wenn ich nun in meinem XMMS-Plugin die URL in ein "file:///pfad/zu/datei" ersetze (d.h. ich will mit xmlParseFile eine lokale Datei parsen), dann geht das ohne Probleme!


    Ich vermute das Problem jetzt an zwei Stellen: entweder kompiliere ich mein XMMS-Plugin falsch oder XMMS sendet an seine Plugins irgendwelche Signale, die dann wiederum eine Funktion in libxml2 (eventuell die, die das XML-Dokument aus dem Netz holt) unterbrechen.
    Für die zweite These spricht übrigens folgende Beobachtung: jedes sleep() in dem XMMS-Plugin (bzw. allgemein in allen XMMS-Plugins) wird unterbrochen und kehrt schon noch kurzer Zeit < 1 sec. in den Plugin-Thread zurück.

    Naja, was ich jetzt gerne wissen würde ist:
    1. wie kommt der Fehler in xmlParseFile() zustande bzw.
    2. wie finde ich das Signal heraus, dass z.B. sleep() unterbricht?

    Bereits vielen Dank fürs Lesen.

    Gruß, Florian

    PS: in den Quellcode zu libxml2 und XMMS habe ich übrigens auch schon reingeschaut. Beim ersteren blicke ich aber überhaupt nicht durch, da würde die Einarbeitung wohl mehrere Wochen dauern, den XMMS Quellcode nehme ich mir jetzt noch mal vor.
    Geändert von ContainerDriver (30-12-2007 um 11:48 Uhr)
    Ein gebrechlich Wesen ist der X-Server.

  2. #2
    Registrierter Benutzer Avatar von undefined
    Registriert seit
    01.03.2004
    Beiträge
    1.255
    Die Entity Fehlermeldung ist völlig korrekt.
    Wie speicherst du die Daten in den Element-knoten?

    PS: Achtung XMMS kann kein UTF-8 gebenenfalls um Konvertieren! Hier mein gegenstück zu ISO-8859-1
    PHP-Code:
    /**
    * xml_ZeichensatzKonverter:
    * @param str  Nicht geprüfte Zeichenkette
    * @return utf8-string
    */
    xmlChar *xml_ZeichensatzKonverter(const char *str)
    {
      
    xmlChar *data;
      
    int retsizeosizebuf;
      
    xmlCharEncodingHandlerPtr utf8encode;

      if (
    strlen(str) == 0)
        return 
    NULL;

      
    utf8encode xmlFindCharEncodingHandler(XML_ENCODING);

      if (!
    utf8encode)
        return 
    NULL;

      
    size = (int) strlen(str) + 1;
      
    osize size 1;
      
    data = (unsigned char *) xmlMalloc((size_tosize);

      if (
    data != 0)
      {
        
    buf size 1;
        
    ret utf8encode->input(data, &osizeBAD_CONST_CAST str, &buf);
        if ((
    ret 0) || (buf size 1))
        {
          
    xmlFree(data);
          
    data 0;
        }
        else
        {
          
    data = (unsigned char *) xmlRealloc(dataosize 1);
          
    data[osize] = 0;
        }
      }

      return 
    data;

    XML_ENCODING steht hierbei auf utf-8
    und BAD_CONST_CAST ist ein const auf BAD_CAST
    Geändert von undefined (30-12-2007 um 15:36 Uhr)
    mfg undefined
    --
    Undefined Behavior (undefiniertes Verhalten) bedeutet meistens etwas ungültiges.
    xhtml Debugger

  3. #3
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    Zitat Zitat von undefined Beitrag anzeigen
    Die Entity Fehlermeldung ist völlig korrekt.
    Wie meinst du das, dass die korrekt ist?

    Wie speicherst du die Daten in den Element-knoten?
    Sorry, wie meinst du das jetzt?

    Ich habe folgenden Code:
    Code:
    xmlDocPtr doc;
    doc = xmlParseFile("...");
    wobei "..." einer URL zu einem XML-Dokument entspricht.

    Wenn ich diese zwei Zeilen in einem extra Programm ausführen lasse (also in der main()-Funktion stehen einfach diese beiden Zeilen), dann wird laufen sie ohne Fehlermeldung durch (in meinem Testprogramm, dass in etwa http://www.xmlsoft.org/tutorial/apd.html enstpricht, kann ich dann auch auf die verschiedenen Elemente im gelesenen XML-Dokument zugreifen).

    Verwende ich diese beiden Zeilen in meinem XMMS-Plugin, dann funktionieren sie in der Regel nicht (es erscheint die obige Fehlermeldung).

    Ich habe da oben in der Regel geschrieben: wenn ich bei XMMS (ich habe es mit der neusten Version und mit der Version 1.2.10 ausprobiert) alle Allgemeinen Plugins (General Plugins) bis auf mein eigenes deaktiviere, dann funktioniert der xmlParseFile-Aufruf (und auch ein sleep()-Aufruf wird nicht unterbrochen); sobald aber noch ein weiteres Plugin läuft, funktioniert xmlParseFile nicht mehr (und sleep() wird unterbrochen). Ich hab testweise mal den XML-Code in ein anderes Plugin eingebaut, dort habe ich das selbe Resultat erhalten: ist nur ein Plugin aktiviert, funktioniert alles (auch sleep()), ab zwei Plugins wird xmlParseFile aber wieder unterbrochen...

    PS: Achtung XMMS kann kein UTF-8 gebenenfalls um Konvertieren! Hier mein gegenstück zu ISO-8859-1
    PHP-Code:
    /**
    * xml_ZeichensatzKonverter:
    * @param str  Nicht geprüfte Zeichenkette
    * @return utf8-string
    */
    xmlChar *xml_ZeichensatzKonverter(const char *str)
    {
      
    xmlChar *data;
      
    int retsizeosizebuf;
      
    xmlCharEncodingHandlerPtr utf8encode;

      if (
    strlen(str) == 0)
        return 
    NULL;

      
    utf8encode xmlFindCharEncodingHandler(XML_ENCODING);

      if (!
    utf8encode)
        return 
    NULL;

      
    size = (int) strlen(str) + 1;
      
    osize size 1;
      
    data = (unsigned char *) xmlMalloc((size_tosize);

      if (
    data != 0)
      {
        
    buf size 1;
        
    ret utf8encode->input(data, &osizeBAD_CONST_CAST str, &buf);
        if ((
    ret 0) || (buf size 1))
        {
          
    xmlFree(data);
          
    data 0;
        }
        else
        {
          
    data = (unsigned char *) xmlRealloc(dataosize 1);
          
    data[osize] = 0;
        }
      }

      return 
    data;

    XML_ENCODING steht hierbei auf utf-8
    und BAD_CONST_CAST ist ein const auf BAD_CAST
    Ein gebrechlich Wesen ist der X-Server.

  4. #4
    Registrierter Benutzer Avatar von undefined
    Registriert seit
    01.03.2004
    Beiträge
    1.255
    Wie meinst du das, dass die korrekt ist?
    Die Meldung besagt das ein nicht erlaubtes Zeichen im Dokument enthalten ist. Und das ist mit & auch der fall. Du kannst nicht einfach einen XMLString laden und weiter geben, dabei erwarten das libXML für dich die Entity Referenzen ohne DTD auflöst und dass mit dem falschen Zeichensatz. So etwas kann nicht gut gehen
    Die richtige Arbeitsweise wäre.
    • Dokument in den Parser laden.
    • Zeichensatz und nicht erlaubte Zeichen Konvertieren.
    • Neu aufbauen
    • Weiter geben

    Alles andere ist Lotterie spielen
    mfg undefined
    --
    Undefined Behavior (undefiniertes Verhalten) bedeutet meistens etwas ungültiges.
    xhtml Debugger

  5. #5
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    Zitat Zitat von undefined Beitrag anzeigen
    Die Meldung besagt das ein nicht erlaubtes Zeichen im Dokument enthalten ist.
    Das "error" davor zeigt aber auch an, dass vorher schon etwas schief gelaufen ist.
    Und das ist mit & auch der fall. Du kannst nicht einfach einen XMLString laden und weiter geben, dabei erwarten das libXML für dich die Entity Referenzen ohne DTD auflöst und dass mit dem falschen Zeichensatz. So etwas kann nicht gut gehen
    Ich glaube wir reden aneinander vorbei.
    Nehmen wir mal die folgende URL: http://musicbrainz.org/ws/1/track/?t...73%62%61%6e%64.
    Da kommt ja im Dokument selber kein unerlaubtes Zeichen vor, oder?
    Und dann folgenden Code:
    Code:
    #include <libxml/parser.h>
    #include <libxml/xpath.h>
    #include <unistd.h>
    
    xmlXPathObjectPtr
    getnodeset (xmlDocPtr doc, xmlChar *xpath){
    
            xmlXPathContextPtr context;
            xmlXPathObjectPtr result;
    
            context = xmlXPathNewContext(doc);
            if (context == NULL) {
                    printf("Error in xmlXPathNewContext\n");
                    return NULL;
            }
            xmlXPathRegisterNs(context,"mmd","http://musicbrainz.org/ns/mmd-1.0#");
            xmlXPathRegisterNs(context,"ext","http://musicbrainz.org/ns/ext-1.0#");
            result = xmlXPathEvalExpression(xpath, context);
            xmlXPathFreeContext(context);
            if (result == NULL) {
                    printf("Error in xmlXPathEvalExpression\n");
                    return NULL;
            }
            if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
                    xmlXPathFreeObject(result);
                    printf("No result\n");
                    return NULL;
            }
            return result;
    }
    int
    main(int argc, char **argv) {
    
            char *docname;
            xmlDocPtr doc;
            xmlChar *xpath =
                (xmlChar*) "//mmd:metadata/mmd:track-list/mmd:track[@ext:score='100']/mmd:artist/mmd:name | "
                         "//mmd:metadata/mmd:track-list/mmd:track[@ext:score='100']/mmd:release-list/mmd:release/mmd:title";
            xmlNodeSetPtr nodeset;
            xmlXPathObjectPtr result;
            int i;
            xmlChar *keyword;
    
            docname = "http://musicbrainz.org/ws/1/track/?type=xml&artist=%54%68%65%20%46%69%65%72%79%20%46%75%72%6e%61%63%65%73&limit=1&title=%41%75%74%6f%6d%61%74%69%63%20%48%75%73%62%61%6e%64";
            doc = xmlParseFile(docname);
            if (doc==NULL)
            {
                    printf("Fehler!\n");
                    return 1;
            }
            result = getnodeset (doc, xpath);
            if (result) {
                    nodeset = result->nodesetval;
                    for (i=0; i < nodeset->nodeNr; i++) {
                            keyword = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
                            printf("name: %s, keyword: %s\n", nodeset->nodeTab[i]->name, keyword);
                            xmlFree(keyword);
                    }
                    xmlXPathFreeObject (result);
            }
            xmlFreeDoc(doc);
            xmlCleanupParser();
    
            return 0;
    }
    .
    Das Kompiliere ich und führe es aus:
    Code:
    florian@leuchtturm0:~/code/pthreads/cover$ gcc -o xpath xpath.c -lxml2 -I/usr/include/libxml2
    florian@leuchtturm0:~/code/pthreads/cover$ ./xpath 
    name: name, keyword: The Fiery Furnaces
    name: title, keyword: Widow City
    florian@leuchtturm0:~/code/pthreads/cover$
    Also läuft da alles wunderbar.
    Mache ich das in XMMS (also einfach
    Code:
            docname = "http://musicbrainz.org/ws/1/track/?type=xml&artist=%54%68%65%20%46%69%65%72%79%20%46%75%72%6e%61%63%65%73&limit=1&title=%41%75%74%6f%6d%61%74%69%63%20%48%75%73%62%61%6e%64";
            doc = xmlParseFile(docname);
    ), dann funktioniert es nicht mehr. Ich glaube eher nicht, dass das etwas mit dem Zeichensatz zu tun hat.

    Die richtige Arbeitsweise wäre.
    • Dokument in den Parser laden.
    Aber hier ist ja schon Schluss im Zusammenhang mit XMMS!

    • Zeichensatz und nicht erlaubte Zeichen Konvertieren.
    • Neu aufbauen
    • Weiter geben

    Alles andere ist Lotterie spielen
    Und was jetzt
    Geändert von ContainerDriver (30-12-2007 um 17:06 Uhr)
    Ein gebrechlich Wesen ist der X-Server.

  6. #6
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    @undefined: habe ich dich verschreckt?


    Ich hab meine Frage/mein Problem mal auf die Mailingliste von libxml2 geschrieben, mal schauen ob ich eine Antwort bekomme.

    Jedenfalls hole ich mir jetzt die Datei erst mit libcurl aus dem Netz um sie dann zu parsen, d.h. ich umgehe das Problem. libcurl brauche ich sowieso, also ist das nicht so tragisch.

    Gruß, Florian
    Ein gebrechlich Wesen ist der X-Server.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •