Вопрос

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

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

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

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

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

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

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

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;
}
Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top