2

在解析像这样的 xml 文件时,我遇到了 rapidxml 的奇怪错误

<?xml version="1.0" encoding="UTF-8"?>
<IMG align="left"
 src="http://www.w3.org/Icons/WWW/w3c_home" />

它抛出“预期>”。我使用如下代码来解析数据

std::fstream file("./test.xml");
std::istream_iterator<char> eos;
std::istream_iterator<char> iit (file);

std::vector<char> xml(iit, eos);
xml.push_back('\0');

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

IMG 抹布中的“/”符号似乎不是问题所在。这是一个 rapidxml 错误还是我做错了什么?

4

3 回答 3

2

将 XML 数据加载到向量中的方式是错误的。在 C++ 文本模式中,流默认设置了“skipws”标志,这会导致它们跳过输入中的所有空格。您可以通过检查向量的内容来验证这一点 - 它会丢失所有空格/结束线。这显然会导致解析器抱怨。

在流上取消设置 skipws 标志以获得正确的行为:

file.unsetf(ios::skipws);

或者,您可以使用 rapidxml_utils.hpp 中的文件类来加载文件:

using namespace rapidxml;
file<> file("test.xml");
xml_document<> doc;
doc.parse<0>(file.data());

遗憾的是,使用 C++ 流加载文本文件非常棘手且充满陷阱。

至于上面的测试,“错误接受”的案例是设计使然(我没有足够的声誉来为他的答案添加评论)。您需要使用“parse_validate_closing_tags”解析标志来使解析器检查结束标签名称是否与起始标签名称匹配:

doc.parse<parse_validate_closing_tags>(...);

请参阅rapidxml手册中的 parse_validate_closing_tags。这种行为的基本原理是性能 - 验证结束标签非常耗时,并且在大多数情况下不需要。

于 2011-07-16T01:02:14.030 回答
1

我只是出于好奇尝试了一下。RapidXml 可能很快,但肯定不是很好

#include "rapidxml.hpp"

int main(int argc, char* args[])
{
        using namespace rapidxml;
        xml_document<> doc;    // character type defaults to char
        doc.parse<0>(args[1]);    // 0 means default parse flags

}

调用它会导致各种有趣的事情:

正确接受:

$ ./test.exe "<hello>world</hello>"

$ ./test.exe '<?xml version="1.0" encoding="UTF-8"?> <IMG align="left" src="http://www.w3.org/Icons/WWW/w3c_home" />'

正确拒绝

$ ./test.exe '<hello we="" / >'
terminate called after throwing an instance of 'rapidxml::parse_error'
  what():  expected >
Aborted (core dumped)

错误地接受:

$ ./test.exe '<hello we="close">world</die><zellq></die>'

$ ./test.exe '<hello we="close/">world</die><we horrible=""></don'\''t>'

YMMV

于 2011-04-19T14:55:18.713 回答
0

您的 XML 有效。如果代码和 XML 与您发布的完全一样,那一定是 rapidxml 错误。我猜它要么不支持在多行之间破坏属性列表,要么不太可能不支持/>标签结尾。

于 2011-04-19T14:06:52.913 回答