Pregunta

Esto puede parecer una pregunta simple.

Pero he estado buscando un analizador XML para usar en una de mis aplicaciones que se ejecuta en Linux.

Estoy usando Expat y he analizado mi archivo XML leyendo uno in. Sin embargo, la salida es la misma que la entrada.

Este es mi archivo en el que estoy leyendo:

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

Sin embargo, después de pasar esto, obtengo exactamente lo mismo que la salida. ¿Me hace preguntarme para qué sirve el analizador?

Solo una cosa más. Estoy usando Expat. Lo cual parece bastante difícil de usar. Mi código está debajo: Esto se lee en un archivo. Pero mi aplicación tendrá que analizar un búfer que será recibido por un socket, y no desde un archivo. ¿Hay alguna muestra de esto que alguien tenga?

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;
}
¿Fue útil?

Solución

Me llevó un tiempo comprender el análisis XML (aunque lo hago en Perl, no en C). Básicamente, registra funciones de devolución de llamada. El analizador hará ping a su devolución de llamada para cada nodo y pasará una estructura de datos que contiene todo tipo de bits jugosos (como texto sin formato, cualquier atributo, nodos secundarios, etc.). Debe mantener algún tipo de información de estado, como un árbol hash en el que se conectan cosas o una cadena que contiene todas las tripas, pero ninguna de las XML.

Solo recuerda que XML no es lineal y no tiene mucho sentido analizarlo como un largo trozo de texto. En cambio, lo analizas como un árbol. Buena suerte.

Otros consejos

Expat es un analizador uniforme. Debe escribir código para tratar con etiquetas, atributos, etc. y luego registrar el código con el analizador. Hay un artículo aquí que describe cómo hacerlo esto.

Con respecto a la lectura desde un socket, dependiendo de su plataforma, puede tratar el socket como si fuera un identificador de archivo. De lo contrario, debe hacer su propia lectura desde el socket y luego pasar los datos para expandirlos explícitamente. Hay una API para hacer esto. Sin embargo, primero trataría de hacerlo funcionar con archivos normales.

En lugar de expatriados, es posible que desee echar un vistazo a libxml2, que probablemente ya esté incluido en su distribución. Es mucho más poderoso que el expatriado, y te ofrece todo tipo de beneficios: DOM (modo árbol), SAX (modo de transmisión), XPath (indispensable para hacer cualquier cosa compleja con XML IMHO) y más. No es tan ligero como el expatriado, pero es mucho más fácil de usar.

Bueno, usted eligió el analizador XML más complicado (los analizadores controlados por eventos son más difíciles de manejar). ¿Por qué Expat y no libxml ?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top