在我的C ++程序中,我想解析一小段XML,插入一些节点,然后提取新的XML(最好是std::string
)。
我已经向我推荐RapidXml,但我看不到如何将XML作为文本字符串检索回来
(我可以迭代节点和属性并自己构建它,但肯定有一个我缺少的功能构建。)
谢谢。
答案 0 :(得分:9)
虽然这个主题的文档很差,但我设法通过查看源代码获得了一些工作代码。虽然它缺少通常包含重要信息的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;
}
答案 1 :(得分:6)
使用print
函数(在rapidxml_print.hpp
实用程序标头中找到)将XML节点内容打印到stringstream
。
答案 2 :(得分:3)
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());
答案 3 :(得分:2)
如果您自己构建XML,请不要忘记转义特殊字符。这往往被忽视,但如果没有实施,可能会引起一些严重的麻烦:
答案 4 :(得分:2)
以下是直接从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
答案 5 :(得分:0)
如果您尚未致力于Rapid XML,我可以推荐一些替代库:
Xerces - 这可能是事实上的C ++实现。
XMLite - 我对这个最小的XML实现运气不错。请参阅http://www.codeproject.com/KB/recipes/xmlite.aspx
答案 6 :(得分:0)
使用static_cast&lt;&gt;
例如:
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());
答案 7 :(得分:0)
以下很容易,
std::string s;
print(back_inserter(s), doc, 0);
cout << s;
您只需在源代码中包含“rapidxml_print.hpp”标题。