【问题标题】:RapidXML weird parsingRapidXML 奇怪的解析
【发布时间】:2012-08-01 22:30:38
【问题描述】:

我有一个非常烦人的问题,我花了好几个小时试图解决它。 我正在使用 rapidXML 和 C++ 来解析 XML 文件:

xml_document<> xmlin;
stringstream input; //initialized somewhere else
xmlin.clear();
xmlin.parse<0>(&(input.str()[0]));

cout << "input:" << input.str() << endl << endl;

xml_node<char> *firstnode = xmlin.first_node();
string s_type = firstnode->first_attribute("type")->value();
cout << "type: " << s_type << endl;

但是我在标准输出上得到了这个:

input:<?xml version="1.0" encoding="utf-8"?><testxml command="testfunction" type="exclusive" />

type: exclusive" /> 

这可能是什么原因(打印 s_type 变量)? 这很烦人,因为我无法很好地处理 xml。

【问题讨论】:

  • 为什么是&amp;(input.str()[0])?使用input.str().c_str()(或者可能是input.str().data())会更清晰。

标签: c++ linux rapidxml


【解决方案1】:

其实我找到了解决办法。

Stringstream 不喜欢它的内容被修改(rapidXML 进行快速的原位解析,这意味着它会修改它获取的数组的内容)。

但是在文档中我读到的字符串类也不喜欢它。

来自 string::c_str 文档页面:

此数组中的值不应在程序中修改

但是当我从流中创建一个字符串时,它正在按预期工作:

xml_document<> xmlin;
stringstream input; //initialized somewhere else
string buffer = input.str()

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

【讨论】:

  • 如果快速 xml 正在修改您传递的缓冲区,您可能应该使用 vector 而不是 string。
  • 它正在修改,因为它需要在每个属性和节点文本的末尾添加 \0 字符,以便能够使用 ->value() 函数正确检索这些值。但是,如果我没记错的话,字符串类可以修改其内容。
  • 原始代码中的真正问题是 stringstream::str() 返回字符串的 copy - 您有效地获取地址然后丢弃。因此,您的 RapidXML 没有修改 stringstream 缓冲区(因为这是不可能的),而是一些随后被覆盖的随机内存......不过,您的新代码看起来是正确的。
【解决方案2】:

我认为问题出在您没有显示的代码中...首先尝试一下,使用文字字符串 - 这对我来说很好...

xml_document<> xmlin;
char *input = "<?xml version=\"1.0\" encoding=\"utf-8\"?><testxml command=\"testfunction\" type=\"exclusive\" />";
xmlin.parse<0>(input);

xml_node<char> *firstnode = xmlin.first_node();
std::string s_type = firstnode->first_attribute("type")->value();

【讨论】:

    【解决方案3】:

    我个人会推荐这种方法

     xml_document<> doc;
     string string_to_parse;                         
     char* buffer = new char[str_to_parse.size() + 1];  
     strcpy (buffer, str_to_parse.c_str());             
    
     doc.parse<0>(buffer);                    
    
     delete [] cstr;  
    

    从要解析的字符串中创建一个非 const char 数组。我一直觉得这种方式更安全、更可靠。

    我曾经做过一些疯狂的事情

     string string_to_parse;  
     doc.parse<0>(const_cast<char*>(string_to_parse.c_str()));
    

    它“工作”了很长时间(直到我需要重用原始字符串的那一天它没有工作)。由于 RapidXML 可以修改它正在解析的 char 数组,并且由于不建议通过 c_str() 更改 str::string,因此我一直使用将字符串复制到非 const char 数组并将其传递给解析器的方法。它可能不是最佳的并且使用额外的内存,但它是可靠的,迄今为止我从未遇到任何错误或问题。您的数据将被解析,并且可以重复使用原始字符串,而不必担心它已被修改。

    【讨论】:

      猜你喜欢
      • 2021-09-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-21
      • 1970-01-01
      • 2015-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多