您的位置:首页 > 其它

tinyXml learning

2015-07-14 11:19 288 查看
some resource come from network, thanks all this people!

#include <string>
#include <iostream>
#include <tinyxml.h>

using std::string;
using std::cout;
using std::endl;

struct xmlNodeList{
TiXmlNode *node;
struct xmlNodeList *next;
struct xmlNodeList *front;
};

void test_char_buffer();
void printMyXml();
void getMyXml();
void writeXmlToDocument();
std::string printAllNode(TiXmlNode * pNode,int childDeep);
TiXmlNode* findTheLastSpecialNode(TiXmlNode * pNode, const std::string&  dstStr, TiXmlNode **resultNode );
xmlNodeList* findAllSpecialNode(TiXmlNode * pNode, const std::string&  dstStr, xmlNodeList **NodeList);

//function: get the node attribute
//[in]:  pNode, the one xml node
//[return]: the current node attribute string, format [name=vale,name=vale,...]
string getNodeAttribute(TiXmlNode * pNode)
{
if(pNode == NULL) return "";
string attributeStr = "";
TiXmlElement * pElement = pNode->ToElement();    //get current node element
TiXmlAttribute * pAttr = pElement->FirstAttribute();   //get the first attribute
string tmpAttrMsg = "";

if( NULL != pAttr )
{
std::string tmpAttrName = "";
std::string tmpAttrVal = "";
do{
tmpAttrName = pAttr->Name();
tmpAttrVal = pAttr->Value();
attributeStr += tmpAttrName+"=" + tmpAttrVal+",";   //split each attribute with  character ','
}while( (pAttr = pAttr->Next() ) );  //look for the other attribute of the current element
attributeStr = attributeStr.erase(attributeStr.find_last_of(","));  //clear the last ','
attributeStr += "]";
}

attributeStr += tmpAttrMsg;
return attributeStr;
}

int main(int argc, char *argv[]) {

// setbuf(stdout,NULL);
// setbuf(stderr,NULL);

// printMyXml();
// getMyXml();
// writeXmlToDocument();

test_char_buffer();
return 0;
}

void printMyXml() {
using namespace std;
TiXmlDocument doc;
const char * xmlFile = "first.xml";
if (doc.LoadFile(xmlFile)) {
doc.Print();
} else {
cout << "can not parse xml first.xml" << endl;
}
}

void getMyXml() {
using namespace std;
const char * xmlFile = "first.xml";
TiXmlDocument doc;
if (doc.LoadFile(xmlFile)) {
//doc.Print();
} else {
cout << "can not parse xml first.xml" << endl;
return;
}
TiXmlElement *rootElement = doc.RootElement();

//get the xml head, the declaration
TiXmlDeclaration* decl = doc.FirstChild()->ToDeclaration();
if(decl){
cout << "xml version: " << decl->Version() << endl;
cout << "xml encoding format: " << decl->Encoding() << endl;
}

TiXmlElement *RootElement = doc.RootElement(); //get the root element
cout << "RootValue: " <<RootElement->Value();  //print the root element value

TiXmlElement *root = rootElement;
TiXmlNode *originalRootContentElement = root->FirstChildElement();
for( TiXmlNode *rootContentElement=originalRootContentElement ; rootContentElement!=NULL ; rootContentElement= rootContentElement->NextSibling() )
{
std::cout<<printAllNode(rootContentElement, 0)<<"\n";
}

TiXmlNode *pRootNode=rootElement->FirstChildElement();

string dstStr= "email";
std::cout<<"look for : " <<dstStr<<endl;
TiXmlNode *res_node;
TiXmlNode *res_node_back_up = res_node;
findTheLastSpecialNode(pRootNode,dstStr,&res_node);
if(res_node_back_up != res_node)
{
std::string nodeStr = res_node->Value();
nodeStr = nodeStr + getNodeAttribute( res_node );
std::cout<<"-----reslut " << nodeStr<<"\n"<<endl;
}

xmlNodeList *result_node=NULL;
dstStr= "email";
std::cout<<"look for : " <<dstStr<<endl;

findAllSpecialNode(pRootNode,dstStr,&result_node);
xmlNodeList *p_result_node=result_node;
for( int i=0 ;p_result_node; p_result_node=p_result_node->next ){
TiXmlNode *res_node = p_result_node->node;
std::string nodeStr = res_node->Value();
nodeStr = nodeStr + getNodeAttribute( res_node );
std::cout<<i++<<"-----reslut  " << nodeStr<<"\n"<<endl;
}

//  TiXmlNode* pNode  = NULL;
//  string msg = "";
//  //  for(pNode=RootElement->FirstChildElement();pNode;pNode=pNode->NextSiblingElement())
//  //  {
//  //      msg += printAllNode(pNode,0);
//  //  }

}

void writeXmlToDocument() {
using namespace std;
const char * xmlFile = "unhappy.xml";
TiXmlDocument doc;
TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "", "");
TiXmlElement * schoolElement = new TiXmlElement( "company" );
TiXmlElement * classElement = new TiXmlElement( "money" );
classElement->SetAttribute("NoOne", "C++");

TiXmlElement * stu1Element = new TiXmlElement("SB1?");
stu1Element->SetAttribute("name", "tinyxml");
stu1Element->SetAttribute("anxiety", "very much");
TiXmlElement * stu1EmailElement = new TiXmlElement("email");
stu1EmailElement->LinkEndChild(new TiXmlText("go to hell 1@welcom.com") );
TiXmlElement * stu1AddressElement = new TiXmlElement("address");
stu1AddressElement->LinkEndChild(new TiXmlText("I don't Know"));
stu1Element->LinkEndChild(stu1EmailElement);
stu1Element->LinkEndChild(stu1AddressElement);

TiXmlElement * stu2Element = new TiXmlElement("SB2?");
stu2Element->SetAttribute("name", "wait");
stu2Element->SetAttribute("unhappy", "very much");
TiXmlElement * stu2EmailElement = new TiXmlElement("email");
stu2EmailElement->LinkEndChild(new TiXmlText("go to hell 2@welcom.com"));
TiXmlElement * stu2AddressElement = new TiXmlElement("address");
stu2AddressElement->LinkEndChild(new TiXmlText("Where?"));
stu2Element->LinkEndChild(stu2EmailElement);
stu2Element->LinkEndChild(stu2AddressElement);

classElement->LinkEndChild(stu1Element);
classElement->LinkEndChild(stu2Element);
schoolElement->LinkEndChild(classElement);

doc.LinkEndChild(decl);
doc.LinkEndChild(schoolElement);
doc.SaveFile(xmlFile);
}

//function: start to print all the element from the pNode
// [in] pNode, the one xml Node element, will start  from this node
// [in] childDeep,  the depth of the current node relative to the original node
// [return],   the structured string
std::string printAllNode(TiXmlNode * pNode,int childDeep)
{
std::string structured_str = "";

if(pNode == NULL){
return "";
}
TiXmlText * pText = NULL;
TiXmlNode * pChildNode = NULL;
int t = pNode->Type();

if(t == TiXmlText::TINYXML_TEXT)  //the node type is TINYXML_TEXT
{
pText = pNode->ToText();
std::string text = pText->Value();
//std::cout<<"TINYXML_TEXT: "<<text<<"\n";
if(!text.empty()){
structured_str = structured_str + "="+ text;
}
} //the node type is TINYXML_ELEMENT
else if(t == TiXmlText::TINYXML_ELEMENT)
{
structured_str = structured_str + "\r\n";
int num = childDeep;
while(num >= 1){
structured_str = structured_str + "\t";
num--;
}
structured_str = structured_str + pNode->Value();
//std::cout<<"TINYXML_TEXT: "<<pNode->Value()<<"\n";
structured_str = structured_str + getNodeAttribute( pNode );
}
//look for the child element
for( pChildNode=pNode->FirstChild() ; pChildNode!=(void*)0 ; pChildNode = pChildNode->NextSibling() )
{
structured_str = structured_str + printAllNode(pChildNode,childDeep+1);
}
return structured_str;
}

//function: find the last matching element
//[in]: pNode ,look for the matching element from the node
//[in]: dstStr, the compare string
//[in]: resultNode, the last matching element
//[return] the last matching element
TiXmlNode* findTheLastSpecialNode(TiXmlNode * pNode, const std::string&  dstStr, TiXmlNode **resultNode )
{
if(!pNode){
return NULL;
}
int t = pNode->Type();

if( TiXmlText::TINYXML_TEXT ==t)   //the node type is TINYXML_TEXT, text node
{
TiXmlText *pText = pNode->ToText();
std::string text = pText->Value();
//std::cout<<"TINYXML_TEXT: "<<text<<"\n";
}
if( TiXmlText::TINYXML_ELEMENT ==t) //the node type is TINYXML_ELEMENT, element node
{
//std::cout<<"TINYXML_ELEMENT: "<<pNode->Value()<<"\n";
std::string text = pNode->Value();
if( 0 == text.compare(dstStr) )
{
*resultNode = pNode;
}
}

for(TiXmlNode *p_child_node=pNode->FirstChild(); p_child_node; p_child_node=p_child_node->NextSibling() )
{
findTheLastSpecialNode(p_child_node,dstStr,resultNode);
}
return *resultNode;
}

//function: find all the special node, return a node list
//[in]: pNode ,look for the matching element from the node
//[in]: the compare string
//[in]: the node list, you should make *NodeList =NULL; becuse *NodeList is the list head
//[return] the list head
xmlNodeList* findAllSpecialNode(TiXmlNode * pNode, const std::string&  dstStr, xmlNodeList **NodeList)
{
if(NULL == pNode){
return NULL;
}
int t = pNode->Type();

if( TiXmlText::TINYXML_TEXT ==t)  //the node type is TINYXML_TEXT, text node
{
TiXmlText *pText = pNode->ToText();
std::string text = pText->Value();
//std::cout<<"TINYXML_TEXT: "<<text<<"\n";
}
else if( TiXmlText::TINYXML_ELEMENT ==t) //the node type is TINYXML_ELEMENT, element node
{
//std::cout<<"TINYXML_ELEMENT: "<<pNode->Value()<<"\n";
std::string text = pNode->Value();
if( 0 == text.compare(dstStr) ){
if(NULL == NodeList )
{
fprintf(stderr,"NodeList = %p error!\n", NodeList);
exit(-1);
}
else
{

xmlNodeList *ptmp =(xmlNodeList*)malloc( sizeof(xmlNodeList) );
if(NULL==ptmp)
{
fprintf(stderr,"malloc memory error!\n");
exit(-1);
}
memset(ptmp, 0, sizeof(ptmp) );

if( NULL==*NodeList )  //list head
{
//DBG_MY_("*NodeList=%p\n",*NodeList);
ptmp->front = NULL;
ptmp->next = NULL;
ptmp->node = pNode;
*NodeList = ptmp;
}
else
{
xmlNodeList* pListHead= *NodeList;
//DBG_MY_("pListHead=%p\n",pListHead);
for( ; NULL!=pListHead->next ; pListHead = pListHead->next  )
;
ptmp->front = pListHead;
ptmp->next = NULL;
ptmp->node = pNode;
pListHead->next = ptmp;
}
}
}
}

for(TiXmlNode *p_child_node=pNode->FirstChild(); p_child_node; p_child_node=p_child_node->NextSibling() )
{
findAllSpecialNode(p_child_node,dstStr,NodeList);
}
return *NodeList;
}

//function: char buffer to xml document
// [in] msgBuf, the char buffer
// [return],
int  bufferToXml(char *msgBuf)
{
TiXmlDocument  buffer ;
buffer.Parse( msgBuf,  0, TIXML_DEFAULT_ENCODING );
TiXmlElement* rootElement = buffer.RootElement();
TiXmlElement* Element = rootElement->FirstChildElement();

std::cout<< printAllNode(rootElement , 0) <<"\n";
return 0;
}

// <?xml version="1.0" encoding="UTF-8"?>
// <recipe>
//  <recipename>Ice Cream Sundae</recipename>
//  <ingredlist>

//      <listitem>
//      <quantity>3</quantity>
//      <itemdescription>chocolate syrup or chocolate fudge</itemdescription>
//      </listitem>

//      <listitem>
//      <quantity>1</quantity>
//      <itemdescription>nuts</itemdescription>
//      </listitem>

//      <listitem>
//      <quantity>1</quantity>
//      <itemdescription>cherry</itemdescription>
//      </listitem>

//  </ingredlist>
//  <preptime>5 minutes</preptime>
// </recipe>
void test_char_buffer()
{
string str123 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
str123 = str123 + "<recipe>";
str123 = str123 + "<recipename>Ice Cream Sundae</recipename>";
str123 = str123 + "<ingredlist>";
str123 = str123 + "<listitem>";
str123 = str123 + "<quantity>3</quantity>";
str123 = str123 + "<itemdescription>chocolate syrup or chocolate fudge</itemdescription>";
str123 = str123 + "</listitem>";
str123 = str123 + "<listitem>";
str123 = str123 + "<quantity>1</quantity>";
str123 = str123 + "<itemdescription>nuts</itemdescription>";
str123 = str123 + "</listitem>";
str123 = str123 + "<listitem>";
str123 = str123 + "<quantity>1</quantity>";
str123 = str123 + "<itemdescription>cherry</itemdescription>";
str123 = str123 + "</listitem>";
str123 = str123 + "</ingredlist>";
str123 = str123 + "<preptime>5 minutes</preptime>";
str123 = str123 + "</recipe>"       ;

char src[4096]={0};

strncpy(src ,str123.c_str(), str123.size() );

printf("\n\n%s\n\n", src);
bufferToXml(src);
}

//function: a example , xml to buffer
void XmlToBuffer(void)
{
TiXmlDocument doc ;
TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0","UTF-8", "" );
doc.LinkEndChild( decl );

TiXmlElement * MESSAGE = new TiXmlElement( "MESSAGE");
MESSAGE->SetAttribute("Version", "1.0");

TiXmlElement * Header = new TiXmlElement( "Header");
Header->SetAttribute("Number", "110");
Header->SetAttribute("ID", "120");

TiXmlElement * Label = new TiXmlElement( "Label");
Label->SetAttribute("Type", "TERMINAL");
Label->SetAttribute("IP", "192.168.1.1");
Label->SetAttribute("Item", "Nothing");

TiXmlElement * Body = new TiXmlElement( "Body");

TiXmlElement* Time = new TiXmlElement("Time");
Time->LinkEndChild(new TiXmlText("1999-9-9") );
TiXmlElement * person = new TiXmlElement("person");
person->LinkEndChild(new TiXmlText("monkey"));
TiXmlElement* action = new TiXmlElement("action");
action->LinkEndChild(new TiXmlText("type the codes") );

MESSAGE->LinkEndChild(Header);
MESSAGE->LinkEndChild(Label);
MESSAGE->LinkEndChild(Body);

Body->LinkEndChild(Time);
Body->LinkEndChild(person);
Body->LinkEndChild(action);

doc.LinkEndChild( MESSAGE );

TiXmlPrinter printer;
doc.Accept( &printer );
doc.SaveFile();

unsigned int xmlLength = printer.Size();
printf("the length of this xml content is %d \n",xmlLength );

char xmlBuffer[1024] = {0};
strncpy(xmlBuffer ,printer.CStr(), sizeof(xmlBuffer)>xmlLength ? xmlLength:sizeof(xmlBuffer) );

printf("cotent :\n%s\n",xmlBuffer );

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: