13

在我的 C++ 程序中,我想解析一小段 XML,插入一些节点,然后提取新的 XML(最好是std::string.
向我推荐了RapidXml,但我看不到如何将 XML 作为文本字符串检索回来。
(我可以遍历节点和属性并自己构建它,但肯定有一个我缺少的内置函数。)
谢谢。

4

8 回答 8

10

尽管该主题的文档很差,但我设法通过查看源代码获得了一些工作代码。虽然它缺少通常包含重要信息的 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;
}
于 2008-09-01T20:52:45.223 回答
6

使用print函数(在rapidxml_print.hpp实用程序标题中找到)将 XML 节点内容打印到stringstream.

于 2008-10-02T12:05:34.507 回答
4

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());
于 2011-12-09T06:59:13.983 回答
2

如果您自己构建 XML,请不要忘记转义特殊字符。这往往被忽视,但如果不实施可能会导致一些严重的问题:

  • <<
  • > >
  • &&
  • “”
  • ''
于 2008-09-01T16:34:59.460 回答
2

以下是直接从RapidXML 手册将节点打印到字符串的方法:

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
于 2010-08-14T16:44:41.920 回答
0

如果您还没有致力于 Rapid XML,我可以推荐一些替代库:

于 2008-09-01T16:29:22.300 回答
0

使用 static_cast<>

前任:

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());
于 2013-02-22T11:50:13.190 回答
0

跟随很容易,

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

您只需在源代码中包含“rapidxml_print.hpp”标头。

于 2013-02-26T10:16:58.157 回答