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。