hamishmcn
hamishmcn

Reputation: 7981

C++: How to extract a string from RapidXml

In my C++ program I want to parse a small piece of XML, insert some nodes, then extract the new XML (preferably as a std::string).
RapidXml has been recommended to me, but I can't see how to retrieve the XML back as a text string.
(I could iterate over the nodes and attributes and build it myself, but surely there's a build in function that I am missing.)

Upvotes: 16

Views: 18789

Answers (8)

duckduckgo
duckduckgo

Reputation: 1295

Following is very easy,

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

You only need to include "rapidxml_print.hpp" header in your source code.

Upvotes: 0

uilianries
uilianries

Reputation: 3887

Use 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());

Upvotes: 0

danath
danath

Reputation: 41

rapidxml::print reuqires an output iterator to generate the output, so a character string works with it. But this is risky because I can not know whether an array with fixed length (like 2048 bytes) is long enough to hold all the content of the XML.

The right way to do this is to pass in an output iterator of a string stream so allow the buffer to be expanded when the XML is being dumped into it.

My code is like below:

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());

Upvotes: 4

Petrus Theron
Petrus Theron

Reputation: 28856

Here's how to print a node to a string straight from the 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

Upvotes: 3

kaalus
kaalus

Reputation:

Use print function (found in rapidxml_print.hpp utility header) to print the XML node contents to a stringstream.

Upvotes: 6

Thomas Watnedal
Thomas Watnedal

Reputation: 4951

Althoug the documentation is poor on this topic, I managed to get some working code by looking at the source. Although it is missing the xml header which normally contains important information. Here is a small example program that does what you are looking for using 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;
}

Upvotes: 11

Adam Tegen
Adam Tegen

Reputation: 25905

If you do build XML yourself, don't forget to escape the special characters. This tends to be overlooked, but can cause some serious headaches if it is not implemented:

  • <        &lt;
  • >        &gt;
  • &        &amp;
  • "        &quot;
  • '        &apos;

Upvotes: 2

Adam Tegen
Adam Tegen

Reputation: 25905

If you aren't yet committed to Rapid XML, I can recommend some alternative libraries:

Upvotes: 0

Related Questions