C ++: Как извлечь строку из RapidXml - PullRequest
13 голосов
/ 01 сентября 2008

В моей программе на C ++ я хочу проанализировать небольшой фрагмент XML, вставить несколько узлов, а затем извлечь новый XML (предпочтительно как std::string).
RapidXml был рекомендован мне, но я не вижу, как извлечь XML обратно в виде текстовой строки.
(Я мог бы перебирать узлы и атрибуты и создавать его самостоятельно, но, безусловно, есть функция сборки, которой мне не хватает.)
Спасибо.

Ответы [ 8 ]

9 голосов
/ 02 сентября 2008

Несмотря на плохую документацию по этой теме, мне удалось получить некоторый рабочий код, посмотрев на исходный код. Хотя в нем отсутствует заголовок xml, который обычно содержит важную информацию. Вот небольшой пример программы, которая делает то, что вы ищете, используя rapidxml:

#include <iostream>
#include <sstream>
#include "rapidxml/rapidxml.hpp"
#include "rapidxml/rapidxml_print.hpp"

int main(int argc, char* argv[]) {
    char xml[] = "<?xml version=\"1.0\" encoding=\"latin-1\"?>"
                 "<book>"
                 "</book>";

    //Parse the original document
    rapidxml::xml_document<> doc;
    doc.parse<0>(xml);
    std::cout << "Name of my first node is: " << doc.first_node()->name() << "\n";

    //Insert something
    rapidxml::xml_node<> *node = doc.allocate_node(rapidxml::node_element, "author", "John Doe");
    doc.first_node()->append_node(node);

    std::stringstream ss;
    ss <<*doc.first_node();
    std::string result_xml = ss.str();
    std::cout <<result_xml<<std::endl;
    return 0;
}
6 голосов
/ 02 октября 2008

Используйте функцию print (находится в служебном заголовке rapidxml_print.hpp), чтобы напечатать содержимое узла XML в stringstream.

3 голосов
/ 09 декабря 2011

rapidxml :: print требует выходного итератора для генерации вывода, поэтому с ним работает символьная строка. Но это рискованно, потому что я не могу знать, достаточно ли длинен массив с фиксированной длиной (например, 2048 байт) для хранения всего содержимого XML.

Правильный способ сделать это - передать выходной итератор потока строк, чтобы разрешить расширение буфера при выгрузке в него XML.

Мой код похож на ниже:

std::stringstream stream;
std::ostream_iterator<char> iter(stream);

rapidxml::print(iter, doc, rapidxml::print_no_indenting);

printf("%s\n", stream.str().c_str());
printf("len = %d\n", stream.str().size());
2 голосов
/ 14 августа 2010

Вот как распечатать узел в строку прямо из RapidXML Manual :

xml_document<> doc;    // character type defaults to char
// ... some code to fill the document

// Print to stream using operator <<
std::cout << doc;   

// Print to stream using print function, specifying printing flags
print(std::cout, doc, 0);   // 0 means default printing flags

// Print to string using output iterator
std::string s;
print(std::back_inserter(s), doc, 0);

// Print to memory buffer using output iterator
char buffer[4096];                      // You are responsible for making the buffer large enough!
char *end = print(buffer, doc, 0);      // end contains pointer to character after last printed character
*end = 0;                               // Add string terminator after XML
2 голосов
/ 01 сентября 2008

Если вы создаете XML самостоятельно, не забудьте экранировать специальные символы. Это, как правило, игнорируется, но может привести к серьезным головным болям, если оно не реализовано:

  • <& lt; </li>
  • > & gt;
  • & &
  • "& quot;
  • & APOS; & APOS;
0 голосов
/ 26 февраля 2013

Следовать очень легко,

std::string s;
print(back_inserter(s), doc, 0);
cout << s;

Вам нужно только включить заголовок «rapidxml_print.hpp» в исходный код.

0 голосов
/ 22 февраля 2013

Использовать static_cast <>

Ex:

rapidxml::xml_document<> doc;
rapidxml::xml_node <> * root_node = doc.first_node();
std::string strBuff;

doc.parse<0>(xml);

.
.
.
strBuff = static_cast<std::string>(root_node->first_attribute("attribute_name")->value());
0 голосов
/ 01 сентября 2008

Если вы еще не привержены Rapid XML, я могу порекомендовать несколько альтернативных библиотек:

  • Xerces - Это, вероятно, реализация C ++ для defacto.

  • XMLite - мне повезло с этой минимальной реализацией XML. Смотрите статью на http://www.codeproject.com/KB/recipes/xmlite.aspx

...