2017-02-08 11 views
1

Я узнаю о libexpat. Я починил этот пример для базового знакомства с помощью API:Обратный вызов XML CharacterDataHandler, не связанный по очереди, несколько раз

Кодекс:

#include <stdio.h> 
#include <expat.h> 
#include <string.h> 
#include <iostream> 

void start(void* userData, const char* name, const char* argv[]) 
{ 
    std::cout << "name: " << name << std::endl; 

    int i = 0; 

    while (argv[i]) 
    { 
    std::cout << "argv[" << i << "] == " << argv[i++] << std::endl; 
    } 
} 

void end(void* userData, const char* name) 
{ 
} 

void value(void* userData, const char* val, int len) 
{ 
    char str[len+1]; 
    strncpy(str, val, len); 
    str[len] = '\0'; 

    std::cout << "value: " << str << std::endl; 
} 

int main(int argc, char* argv[], char* envz[]) 
{ 
    XML_Parser parser = XML_ParserCreate(NULL); 
    XML_SetElementHandler(parser, start, end); 
    XML_SetCharacterDataHandler(parser, value); 

    int bytesRead = 0; 
    char val[1024] = {}; 
    FILE* fp = fopen("./catalog.xml", "r"); 
    std::cout << "fp == 0x" << (void*)fp << std::endl; 

    do 
    { 
    bytesRead = fread(val, 1, sizeof(val), fp); 
    std::cout << "In while loop bytesRead==" << bytesRead << std::endl; 

    if (0 == XML_Parse(parser, val, bytesRead, (bytesRead < sizeof(val)))) 
    { 
     break; 
    } 
    } 
    while (1); 

    XML_ParserFree(parser); 
    std::cout << __FUNCTION__ << " end" << std::endl; 

    return 0; 
} 

catalog.xml:

<CATALOG> 
    <CD key1="value1" key2="value2"> 
     <TITLE>Empire Burlesque</TITLE> 
     <ARTIST>Bob Dylan</ARTIST> 
     <YEAR>1995</YEAR> 
    </CD> 
</CATALOG> 

Makefile:

xml: xml.o 
     g++ xml.o -lexpat -o xml 

xml.o: main.cpp Makefile 
     g++ -g -c main.cpp -o xml.o 

Выход:

fp == 0x0x22beb50 
In while loop bytesRead==148 
name: CATALOG 
value: 

value:  
name: CD 
argv[1] == key1 
argv[2] == value1 
argv[3] == key2 
argv[4] == value2 
value: 

value: 
name: TITLE 
value: Empire Burlesque 
value: 

value: 
name: ARTIST 
value: Bob Dylan 
value: 

value: 
name: YEAR 
value: 1995 
value: 

value:  
value: 

In while loop bytesRead==0 
main end 

Вопрос:

С выхода, кажется, что обратный вызов я установил с XML_SetCharacterDataHandler() вызывается дважды для каталога ,, CD, название и ХУДОЖНИК тегов XML , а затем несколько раз для тега YEAR - может кто-нибудь объяснить это поведение? Из отмеченного catalog.xml мне непонятно, почему (или когда-либо было) несколько значений, связанных с любыми тегами XML.

спасибо.

Цитирование:

Кредит this site на основе приведенного выше примера кода.

ответ

1

Анализатор expatmay разделяет текстовые узлы на несколько вызовов обработчику данных символов. Чтобы правильно обрабатывать текстовые узлы, вы должны накапливать текст по нескольким вызовам и обрабатывать его при получении события «end» для содержащего тега.

Это правда в целом даже в разных синтаксических разборах и разных языках - то есть то же самое верно в Java.

Смотри, например http://marcomaggi.github.io/docs/expat.html#using-comm

Обычная первый раз ошибка с любым из интерфейсов событийно-ориентированный на XML-парсер ожидать весь текст, содержащийся в элементе, чтобы сообщаться один вызовом обработчик символьных данных. Expat, как и многие другие синтаксические анализаторы XML, сообщает такие данные, как последовательность вызовов; нет никакого способа узнать, когда конец последовательности достигнут, пока не будет выполнен другой обратный вызов.

Кроме того, из the expat documentation

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

+0

Правильно ли я понимаю: каждый раз, когда вызывается обратный вызов 'start', я должен отметить аргумент' name'. Например.предположим, что начальный обратный вызов был вызван с помощью 'name == 'foo" ', тогда значение foo tag фактически является накоплением всех строк, переданных в обратный вызов обработчика данных, и что накопление может быть прекращено, когда вызываемый обратный вызов вызван с 'имя == "Foo"'. – StoneThrow

+0

Я думаю, что что-то не в моих силах: начальный обратный вызов для тега «TITLE» вызывается до завершения обратного вызова для «КАТАЛОГ» - поэтому я думаю, что это означает, что значение TITLE накапливается до последующего вызова начального обратного вызова с другим именем. ..? – StoneThrow

+0

_ callback для тега «TITLE» вызывается до завершения обратного вызова для «КАТАЛОГ» _ - Это правда, конец элемента '' еще не произошел. Это не произойдет до самого конца документа, когда встречается ''. Почему вы ожидаете увидеть его перед началом - '' событие? – <span class="text-secondary"> <small> <span></span> </small> </span> </p> </div> </div> </div> </div> </div> </article> <div> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-6208739752673518" data-ad-slot="1038284119" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div> <div class="clearfix"> </div> <div> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <ins class="adsbygoogle" style="display:block" data-ad-format="autorelaxed" data-ad-client="ca-pub-6208739752673518" data-ad-slot="1575177025"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> <div class="padding-top-10"></div> </div> </div> <script type="text/javascript" src="http://img.uwenku.com/uwenku/script/side.js?t=1644592048337"></script> <script type="text/javascript" src="http://img.uwenku.com/uwenku/plugin/highlight/highlight.pack.js"></script> <link href="http://img.uwenku.com/uwenku/plugin/highlight/styles/docco.css" media="screen" rel="stylesheet" type="text/css" /> <script type="text/javascript"> $('pre').each(function(i, e) { hljs.highlightBlock(e, "<span class='indent'> </span>", false) }); </script> <div class="col-lg-3 col-md-4 col-sm-5"> <div id="rightTop"> <div class="row"> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-6208739752673518" data-ad-slot="5415218910" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> <div class="row sidebar panel panel-default"> <div class="panel-heading font-bold"> Последний вопрос </div> <div class="m-b-sm m-t-sm clearfix"> <ul class="side_article_list"> <li class="side_article_list_item"> 1. <a href="http://ru.uwenku.com/question/p-sfnjsqzk-yy.html" target="_blank" title="Как отсортировать массив дочерних элементов для столбца «product_in_stock». Virtuemart 3"> Как отсортировать массив дочерних элементов для столбца «product_in_stock». Virtuemart 3 </a> </li> <li class="side_article_list_item"> 2. <a href="http://ru.uwenku.com/question/p-sijqphfm-zh.html" target="_blank" title="Выберите следующие 7 дней, используя только день и месяц"> Выберите следующие 7 дней, используя только день и месяц </a> </li> <li class="side_article_list_item"> 3. <a href="http://ru.uwenku.com/question/p-ymvbmphf-xo.html" target="_blank" title="выполнение Exception с Drools (java.lang.ClassCastException: org.drools.io.impl.ClassPathResource не может быть приведен к org.drools.io.InternalResource)"> выполнение Exception с Drools (java.lang.ClassCastException: org.drools.io.impl.ClassPathResource не может быть приведен к org.drools.io.InternalResource) </a> </li> <li class="side_article_list_item"> 4. <a href="http://ru.uwenku.com/question/p-ptbgxlwa-xc.html" target="_blank" title="Excel: получить местоположение первой и последней ненулевой ячейки в строке"> Excel: получить местоположение первой и последней ненулевой ячейки в строке </a> </li> <li class="side_article_list_item"> 5. <a href="http://ru.uwenku.com/question/p-zjrbskyw-ye.html" target="_blank" title="Visual Basic 6 и Visual Basic в Visual studio"> Visual Basic 6 и Visual Basic в Visual studio </a> </li> <li class="side_article_list_item"> 6. <a href="http://ru.uwenku.com/question/p-xogfkwtb-uy.html" target="_blank" title="linux kernel_v_4.X замедляет пропускную способность TCP_UL"> linux kernel_v_4.X замедляет пропускную способность TCP_UL </a> </li> <li class="side_article_list_item"> 7. <a href="http://ru.uwenku.com/question/p-akmwiphk-vh.html" target="_blank" title="Когда вы можете увидеть эффект от вашего обновления, вставить и удалить во время вызова хранимой процедуры?"> Когда вы можете увидеть эффект от вашего обновления, вставить и удалить во время вызова хранимой процедуры? </a> </li> <li class="side_article_list_item"> 8. <a href="http://ru.uwenku.com/question/p-qznisqdh-tc.html" target="_blank" title="Сигнал между QML с Repeater"> Сигнал между QML с Repeater </a> </li> <li class="side_article_list_item"> 9. <a href="http://ru.uwenku.com/question/p-rqbbgjso-to.html" target="_blank" title="вызовов, работающие с машинописью напечатали моделей при взаимодействии с RESTful API"> вызовов, работающие с машинописью напечатали моделей при взаимодействии с RESTful API </a> </li> <li class="side_article_list_item"> 10. <a href="http://ru.uwenku.com/question/p-ksagdtve-sm.html" target="_blank" title="Jquery Datatable перетаскивание строк, строка переназначения из данных JSon"> Jquery Datatable перетаскивание строк, строка переназначения из данных JSon </a> </li> </ul> </div> </div> </div> <p class="article-nav-bar"></p> <div class="row sidebar article-nav"> <div class="row box_white visible-sm visible-md visible-lg margin-zero"> <div class="top"> <h3 class="title"><i class="glyphicon glyphicon-th-list"></i> Смежные вопросы</h3> </div> <div class="article-relative-content"> <ul class="side_article_list"> <li class="side_article_list_item">Нет связанных вопросов^_^</li> </ul> </div> </div> </div> </div> </div> </div> </div><!-- wrap end--> <!-- footer --> <footer id="footer"> <div class="bg-simple lt"> <div class="container"> <div class="row padder-v m-t"> <div class="col-xs-8"> <ul class="list-inline"> <li><a href="http://ru.uwenku.com/contact">Свяжитесь с нами</a></li> <li>© 2020 RU.UWENKU.COM</li> <li><a target="_blank" href="https://beian.miit.gov.cn/">沪ICP备13005482号-4</a></li> <li><script type="text/javascript" src="https://v1.cnzz.com/z_stat.php?id=1280101193&web_id=1280101193"></script></li> <li><a href="http://www.uwenku.com/" target="_blank" title="优文库">简体中文</a></li> <li><a href="http://hk.uwenku.com/" target="_blank" title="優文庫">繁體中文</a></li> <li><a href="http://ru.uwenku.com/" target="_blank" title="поле вопросов и ответов">Русский</a></li> <li><a href="http://de.uwenku.com/" target="_blank" title="Frage - und - antwort - Park">Deutsch</a></li> <li><a href="http://es.uwenku.com/" target="_blank" title="Preguntas y respuestas">Español</a></li> <li><a href="http://hi.uwenku.com/" target="_blank" title="कार्यक्रम प्रश्न और उत्तर पार्क">हिन्दी</a></li> <li><a href="http://it.uwenku.com/" target="_blank" title="IL Programma di chiedere Park">Italiano</a></li> <li><a href="http://ja.uwenku.com/" target="_blank" title="プログラム問答園区">日本語</a></li> <li><a href="http://ko.uwenku.com/" target="_blank" title="프로그램 문답 단지">한국어</a></li> <li><a href="http://pl.uwenku.com/" target="_blank" title="program o park">Polski</a></li> <li><a href="http://tr.uwenku.com/" target="_blank" title="Program soru ve cevap parkı">Türkçe</a></li> <li><a href="http://vi.uwenku.com/" target="_blank" title="Đáp ứng viên">Tiếng Việt</a></li> <li><a href="http://fr.uwenku.com/" target="_blank" title="Programme interrogation Park">Française</a></li> </ul> </div> </div> </div> </div> </div> </footer> <!-- / footer --> <script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?f78a970f17b19a79fc477a3378096f29"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script> </body> </html>