【问题标题】:How to parse an XML file with RapidXml如何使用 RapidXml 解析 XML 文件
【发布时间】:2010-05-11 04:12:28
【问题描述】:

我必须在 C++ 中解析一个 XML 文件。我正在研究并为此找到了 RapidXml 库。

我对@9​​87654321@有疑问。

xml 可以是 .xml 文件还是必须是 stringchar *

如果我只能使用stringchar *,那么我想我需要读取整个文件并将其存储在一个字符数组中并将其指针传递给函数?

有没有办法直接使用文件,因为我还需要更改代码中的 XML 文件。

如果这在 RapidXml 中是不可能的,那么请推荐一些其他 C++ 中的 XML 库。

谢谢!!!

灰烬

【问题讨论】:

  • xml_document::parse() 的参数是一个包含 xml 的以零结尾的字符串。所以你只需要创建一个 file2string 函数。将文件读入 vector 缓冲区,然后将 &buffer[0] 传递给 parse()。

标签: c++ xml parsing rapidxml


【解决方案1】:

RapidXml 带有一个类来为您执行此操作,rapidxml::filerapidxml_utils.hpp 文件中。 比如:

#include "rapidxml_utils.hpp"

int main() {
    rapidxml::file<> xmlFile("somefile.xml"); // Default template is char
    rapidxml::xml_document<> doc;
    doc.parse<0>(xmlFile.data());
...
}

请注意,xmlFile 对象现在包含 XML 的所有数据,这意味着一旦超出范围并被销毁,doc 变量将不再安全可用。如果您在函数内部调用 parse,则必须以某种方式将 xmlFile 对象保留在内存中(全局变量、新变量等),以便文档保持有效。

【讨论】:

  • 我是 C++ 新手,但函数 xmlFile() 定义在哪里?我在任何头文件中都找不到它。
  • xmlFile 是一个变量而不是一个函数 - 所以这是定义
  • 那为什么要带参数呢?这在 C++ 中是什么意思
【解决方案2】:

我自己是 C++ 新手...但我想分享一个解决方案。

YMMV!

thread 上向 SiCrane 大喊: -- 只是用向量替换 'string' ---(感谢 anno)

请评论并帮助我学习!我对此很陌生

无论如何,这似乎是一个好的开始:

#include <iostream>
#include <fstream>
#include <vector>

#include "../../rapidxml/rapidxml.hpp"

using namespace std;

int main(){
   ifstream myfile("sampleconfig.xml");
   rapidxml::xml_document<> doc;

   /* "Read file into vector<char>"  See linked thread above*/
   vector<char> buffer((istreambuf_iterator<char>(myfile)), istreambuf_iterator<char>( ));

   buffer.push_back('\0');

   cout<<&buffer[0]<<endl; /*test the buffer */

   doc.parse<0>(&buffer[0]); 

   cout << "Name of my first node is: " << doc.first_node()->name() << "\n";  /*test the xml_document */


}

【讨论】:

  • 这很好用,但前提是 'vector buffer' 不超出范围:解决这个问题的快速而肮脏的方法是向向量添加 'static' 关键字,但是我不认为这真的很干净。看到这个:stackoverflow.com/questions/6363719/…
【解决方案3】:

我们通常将 XML 从磁盘读取到 std::string,然后将其安全复制到 std::vector&lt;char&gt; 中,如下所示:

string input_xml;
string line;
ifstream in("demo.xml");

// read file into input_xml
while(getline(in,line))
    input_xml += line;

// make a safe-to-modify copy of input_xml
// (you should never modify the contents of an std::string directly)
vector<char> xml_copy(input_xml.begin(), input_xml.end());
xml_copy.push_back('\0');

// only use xml_copy from here on!
xml_document<> doc;
// we are choosing to parse the XML declaration
// parse_no_data_nodes prevents RapidXML from using the somewhat surprising
// behavior of having both values and data nodes, and having data nodes take
// precedence over values when printing
// >>> note that this will skip parsing of CDATA nodes <<<
doc.parse<parse_declaration_node | parse_no_data_nodes>(&xml_copy[0]);

完整的源代码检查:

Read a line from xml file using C++

【讨论】:

  • 由于调整矢量大小,这太慢了。与 Superfly Jon 的答案相比,它要快得多。
【解决方案4】:

manual 告诉我们:

函数 xml_document::parse

[...] 解析以零结尾的 XML 字符串 根据给定的标志。

RapidXML 将文件中的字符数据加载给您。要么将文件读入缓冲区,如建议的anno,要么使用一些内存映射技术。 (但请先查看parse_non_destructive 标志。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-20
    • 1970-01-01
    • 2013-08-27
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2014-09-07
    相关资源
    最近更新 更多