tinyXml learning

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 );

}           




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值