libxml库中Node, contentNode还有Element的概念很容易混淆。 做了好几个sample test我才算是区分清楚。xmlpp::Node是base class. xmlpp::contentNode和xmlpp::Element都继承于它。xmlpp::Element的概念很容易理解。就是我们平时理解的xml的element,它可以有attribute,也可以有自己的子节点。 libxml++库里面xmlpp::contentNode这个名字我觉得取得非常不好, 非常让我产生误解。其实它就是指xml里面的空白以及注释。 我写了一个小程序做了验证。
#include <iostream>
#include <string>
#include "libxml++/libxml++.h"
#include <libxml++/nodes/node.h>
using namespace std;
int main()
{
string file_name = "example.xml";
xmlpp::DomParser parser;
parser.parse_file( file_name );
if (parser)
{
// get root node
xmlpp::Node* pNode = parser.get_document() -> get_root_node();
cout << "root element is /""<< pNode -> get_name() << "/"" << endl;
xmlpp::Node::NodeList node_list = pNode -> get_children();
xmlpp::Node::NodeList::iterator iter = node_list.begin();
for(; iter != node_list.end(); ++iter )
{
xmlpp::ContentNode * content = dynamic_cast<xmlpp::ContentNode *>(*iter);
if ( NULL == content )
cout << (*iter) -> get_name() << endl;
else
cout << "coutent is NULL" << endl;
}
}
else
{
cout << "cannot open " << file_name << endl;
}
return 0;
}
下面这个是example.xml
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<node1 a="10">aaaaa</node1>
<node2 b="20">bbbbb</node2>
</root>
Makefile 还是用的前一篇文章的。 输出结果是
root element is "root"
coutent is NULL
node1
coutent is NULL
node2
coutent is NULL
这里有三个"content is NULL"。 其中第一个是<root>和<node1 a="10">aaaaa</node1>之间的空白
第二个是</node1>和<node2>之间的空白。第三个是</node2>和</root>之间的空白。
为了验证我的猜测是正确的, 我将example.xml做了下调整
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<node1 a="10">aaaaa</node1>
<node2 b="20">bbbbb</node2></root>
</node2>后面紧跟</root>。 将之前的换行符删除。 现在的运行结果是
root element is "root"
coutent is NULL
node1
coutent is NULL
node2
只有两个"content is NULL"。
所以在代码中 xmlpp::Node::NodeList node_list = pNode -> get_children(); 获取nodelist后 遍历每个Node时,将其cast成的ContentNode指针为空时说明现在找到的是我们需要的Element。 当然这里也可以cast成Element指针。 当Element指针不为空时就是我们要找的Element。