使用 PugiXML 进行 XML 解析,无限循环
这几乎是我制作的第一个 C++ 程序,它应该在文档中显示 xml 节点列表。我使用 TinyXML 做了一个完全相同的事情,但我发现 Pugi 更好并且想继续使用它。
程序代码:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#include "pugixml/src/pugixml.hpp"
#include "pugixml/src/pugiconfig.hpp"
#include "pugixml/src/pugixml.cpp"
using namespace pugi;
const char * identify(xml_node node)
{
const char * type;
switch(node.type())
{
case node_null:
type = "Null";
break;
case node_document:
type = "Document";
break;
case node_element:
type = "Element";
break;
case node_pcdata:
type = "PCDATA";
break;
case node_cdata:
type = "CDATA";
break;
case node_comment:
type = "Comment";
break;
case node_pi:
type = "Pi";
break;
case node_declaration:
type = "Declaration";
break;
case node_doctype:
type = "Doctype";
break;
default:
type = "Invalid";
}
return type;
}
void walk(xml_node parent)
{
printf("%s:\t%s\t%s\n", identify(parent), parent.name(), parent.value());
for(xml_node child = parent.first_child(); child != 0; child = parent.next_sibling())
{
walk(child);
}
}
int main(int argc, char* argv[])
{
for (int i=1; i<argc; i++)
{
xml_document doc;
xml_parse_result result = doc.load_file(argv[i]);
cout << argv[i] << ": " << result.description() << endl;
if (result)
{
walk(doc);
}
}
return 0;
}
示例 XML:
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<iOne>
<iTwo>
<iThree>
<one>1</one>
<two>2</two>
<three>3</three>
</iThree>
</iTwo>
<one>1</one>
<two>2</two>
<three>3</three>
</iOne>
该代码一直有效,直到遇到两个
中的第一个并进入无限循环,这让我认为 中的条件有问题>for(xml_node child =parent.first_child(); child != 0; child =parent.next_sibling())
但一切都与示例中相同吗?我可能错过了一些非常明显的东西......不过,这些是我在 C++ 中的第一个婴儿步骤:)
我知道 C++ 中的 NULL 只是 0,对吧?
另外(抱歉问了多个问题),这真的是用 pugi 做事的正确方法吗?对于C++程序,我似乎不太使用指针?我很困惑。
this is pretty much the first C++ program that I ever made, it should display a list of xml nodes in the document. I made an exact same thing work using TinyXML, but I find Pugi much nicer and would like to continue using it.
Program code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#include "pugixml/src/pugixml.hpp"
#include "pugixml/src/pugiconfig.hpp"
#include "pugixml/src/pugixml.cpp"
using namespace pugi;
const char * identify(xml_node node)
{
const char * type;
switch(node.type())
{
case node_null:
type = "Null";
break;
case node_document:
type = "Document";
break;
case node_element:
type = "Element";
break;
case node_pcdata:
type = "PCDATA";
break;
case node_cdata:
type = "CDATA";
break;
case node_comment:
type = "Comment";
break;
case node_pi:
type = "Pi";
break;
case node_declaration:
type = "Declaration";
break;
case node_doctype:
type = "Doctype";
break;
default:
type = "Invalid";
}
return type;
}
void walk(xml_node parent)
{
printf("%s:\t%s\t%s\n", identify(parent), parent.name(), parent.value());
for(xml_node child = parent.first_child(); child != 0; child = parent.next_sibling())
{
walk(child);
}
}
int main(int argc, char* argv[])
{
for (int i=1; i<argc; i++)
{
xml_document doc;
xml_parse_result result = doc.load_file(argv[i]);
cout << argv[i] << ": " << result.description() << endl;
if (result)
{
walk(doc);
}
}
return 0;
}
Sample XML:
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<iOne>
<iTwo>
<iThree>
<one>1</one>
<two>2</two>
<three>3</three>
</iThree>
</iTwo>
<one>1</one>
<two>2</two>
<three>3</three>
</iOne>
The code works until it comes across the first of the two <three>
s and goes into an infinite loop, which mades me think there is something wrong with condition in for(xml_node child = parent.first_child(); child != 0; child = parent.next_sibling())
but everything is the same as in examples? I probably missed something pretty obvious... these are my first baby steps in c++ though :)
I am given to understand NULL in C++ is just 0 right?
Also (sorry for asking multiple questions), is this really a correct way of doing stuff with pugi? For a C++ program, I dont seem to be using pointers much? Im confused.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您是否尝试过将
for
循环更改为:这就是示例的执行方式(traverse_base.cpp 例如)。
重要的部分是
child = child.next_sibling()
,而不是parent.next_sibling()
。Have you tried changing that
for
loop to:This is how the samples do it (traverse_base.cpp for example).
The important part is
child = child.next_sibling()
, notparent.next_sibling()
.