Что такое парсер XML? Использование Expat

Это может показаться простым вопросом.

Но я искал парсер XML для использования в одном из моих приложений, работающих на Linux.

Я использую Expat и проанализировал мой XML-файл, прочитав один из них. Однако выходные данные совпадают с входными данными.

Это мой файл, в котором я читаю:

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

Тем не менее, после того, как я прошел это, я получаю точно так же, как вывод. Это заставляет меня задуматься, для чего нужен парсер?

Еще одна вещь. Я использую Expat. Который кажется довольно сложным в использовании. Мой код ниже: это читает в файле. Но моему приложению придется анализировать буфер, который будет получен сокетом, а не из файла. Есть ли образцы этого, которые есть у кого-нибудь?

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

4 ответа

Решение

Потребовалось некоторое время, чтобы обернуться вокруг анализа XML (хотя я делаю это на Perl, а не на C). В основном, вы регистрируете функции обратного вызова. Парсер будет проверять ваш обратный вызов для каждого узла и передавать в структуру данных, содержащую все виды сочных битов (таких как открытый текст, любые атрибуты, дочерние узлы и т. Д.). Вы должны поддерживать некоторую информацию о состоянии - например, хеш-дерево, в которое вы вставляете вещи, или строку, содержащую все кишки, но не XML.

Просто помните, что XML не является линейным, и нет смысла анализировать его как длинный кусок текста. Вместо этого вы анализируете это как дерево. Удачи.

Expat - это четный парсер. Вы должны написать код для работы с тегами, атрибутами и т. Д., А затем зарегистрировать код в парсере. Здесь есть статья, которая описывает, как это сделать.

Что касается чтения из сокета, в зависимости от вашей платформы вы можете рассматривать сокет как дескриптор файла. В противном случае вам нужно выполнить собственное чтение из сокета, а затем передать данные в явном виде. Для этого есть API. Тем не менее, я бы сначала попытался заставить его работать с обычными файлами.

Вместо экспата, вы можете захотеть взглянуть на libxml2, который, вероятно, уже включен в ваш дистрибутив. Он намного мощнее, чем expat, и дает вам много всяких полезностей: DOM (древовидный режим), SAX (потоковый режим), XPath (необходим для выполнения любых сложных задач с XML IMHO) и многое другое. Он не такой легкий, как эмигрант, но его намного проще использовать.

Ну, вы выбрали самый сложный синтаксический анализатор XML (управляемые событиями парсеры сложнее обрабатывать). Почему Expat, а не libxml?

Другие вопросы по тегам