LINUX.ORG.RU

Бага в libxml2?

 


0

1

Пишу свой парсер, сверяюсь с libxml2 как образцом. сейчас подобрался к парсингу префиксов-неймспейсов. Ощущение что libxml2 не умеет с ними корректно работать вообще:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <aaa xmlns:de="http://www.dolby.com/dcinema/ws/smi/v11/SPL"        atr="abc"       xmlns:fe="http://somewhere">
   some text
   <de:bbb atr1="abb"  atr2="baa" >aaa</de:bbb>
   <de:ccc>aaa</de:ccc>
   <fe:ddd>bbb</fe:ddd>
   some more text
  </aaa>

XML валидный, проверено.

Что я получаю в итоге у себя (не обрабатываю неймспейсы пока):
space - text
* - attribute
$ - PI
+ - node
} - namespace definition
{ - namespace use

{
    '$xml' => {
        '*version' => '1.0',
        '*encoding' => 'UTF-8',
        '*standalone' => 'yes',
        ' xml' => '\x0A  ',
    },
    '+aaa' => {
        '*xmlns:de' => 'http://www.dolby.com/dcinema/ws/smi/v11/SPL',
        '*atr' => 'abc',
        '*xmlns:fe' => 'http://somewhere',
        ' aaa' => '\x0A   some text\x0A   ',
        '+de:bbb' => {
            '*atr1' => 'abb',
            '*atr2' => 'baa',
            ' de:bbb' => 'aaa',
        },
        ' aaa' => '\x0A   ',
        '+de:ccc' => {
            ' de:ccc' => 'aaa',
        },
        ' aaa' => '\x0A   ',
        '+fe:ddd' => {
            ' fe:ddd' => 'bbb',
        },
        ' aaa' => '\x0A   some more text\x0A  ',
    },
},

Что я получаю у libxml2:

{
    '+aaa' => {
        ' aaa' => '\x0A   some text\x0A   ',
        '+bbb' => {
            ' bbb' => 'aaa',
            '*atr1' => 'abb',
            '*atr2' => 'baa',
            '}de' => 'http://www.dolby.com/dcinema/ws/smi/v11/SPL',
            '}fe' => 'http://somewhere',
        },
        ' aaa' => '\x0A   ',
        '+ccc' => {
            ' ccc' => 'aaa',
            '}de' => 'http://www.dolby.com/dcinema/ws/smi/v11/SPL',
            '}fe' => 'http://somewhere',
        },
        ' aaa' => '\x0A   ',
        '+ddd' => {
            ' ddd' => 'bbb',
            '}fe' => 'http://somewhere',
        },
        ' aaa' => '\x0A   some more text\x0A  ',
        '*atr' => 'abc',
        '{de' => 'http://www.dolby.com/dcinema/ws/smi/v11/SPL',
        '{fe' => 'http://somewhere',
    },
},
Обратите внимание, что он пририсовал bbb сразу два неймспейса, пририсовал ccc сразу два неймспейса и пририсовал один (правильно) неймспейс для ddd.

ЧЯДНТ? Бага? Фича?

★★★★★

Последнее исправление: PPP328 (всего исправлений: 1)

Я бы проверил как оно в других реализациях и перечитал ещё раз мануал.

anonymous
()
Ответ на: комментарий от anonymous

Вот минимальный код

#include <stdio.h>
#include <libxml/xmlreader.h>
#include <libxml/tree.h>

char xml_data[] = {
    "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
    "  <aaa xmlns:de=\"http://www.dolby.com/dcinema/ws/smi/v11/SPL\" "
    "       atr=\"abc\""
    "       xmlns:fe=\"http://somewhere\">\n"
    "   some text\n"
    "   <de:bbb atr1=\"abb\"  atr2=\"baa\" >aaa</de:bbb>\n"
    "   <de:ccc>aaa</de:ccc>\n"
    "   <fe:ddd>bbb</fe:ddd>\n"
    "   some more text\n"
    "  </aaa>"
};

void printns(xmlNsPtr ns, int deep, char * marker)
{
    while (ns)
    {
        printf("%*c%s+%s\n", deep * 5 + 1, ' ', marker, ns->prefix);
        ns = ns->next;
    }
}

void printelem(xmlNodePtr ptr, int deep)
{
    printf("%*c%s\n", deep * 5, ' ', ptr->name);
    if (ptr->type == XML_ELEMENT_NODE) 
    {
        printns(ptr->nsDef, deep, "d");
        printns(ptr->ns,    deep, "u");
    }

    if (ptr->xmlChildrenNode) printelem(ptr->xmlChildrenNode, deep+1);

    if (ptr->next) printelem(ptr->next, deep);
}

int main(void)
{
    LIBXML_TEST_VERSION
    xmlInitParser();

    xmlDocPtr doc;
    doc = xmlReadDoc(BAD_CAST xml_data, NULL, NULL, XML_PARSE_NOBLANKS);

    printelem(doc->xmlChildrenNode, 1);

    xmlFreeDoc(doc);
alex@alex:~/Проекты/test/xml2$ gcc test.c -o test.elf -I/usr/include/libxml2 -lxml2 && ./test.elf
     aaa
      d+de
      d+fe
          text
          bbb
           u+de
           u+fe
               text
          text
          ccc
           u+de
           u+fe
               text
          text
          ddd
           u+fe
               text
          text

PPP328 ★★★★★
() автор топика

В общем эта зараза не создает ноду с неймспейсом, а просто тыкает ссылку на nsDef в указатель ns. Очевидно что ппц.

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

вроде такая распространённая либа

Это не одна либа, а огромная куча кода, сваленная вместе. Что-то инфернальное внутри. Чего только их дерево стоит, где данные и состояние итерации хранятся прямо рядом, в одних и тех же узлах. А хитрый алгоритм обхода этого дерева просто реплицирован по коду вместо изоляции куда-нибудь. Хотя бы в препроцессорную магию, как в Linux.

А ещё в коде libxml2 есть FTP-сервер. Круто, да?

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от i-rinat

FTP-сервер

лол, серьёзно? а зачем он там? ладно бы клиент, я бы может ещё понял, но сервер-то нахрена?

anonymous
()
Ответ на: комментарий от anonymous

FTP-сервер

А, не, похоже это всё-таки клиент.

i-rinat ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.