C + + read XML File Sample _c language

Source: Internet
Author: User
Tags gettext

Recently to do a VRP algorithm, the test set are placed in the XML file, and my algorithm uses C + + to write, so need to use C + + to read XML files.

Search on Baidu "C + + read XML file", can come out a lot of blogs, mostly about tinyxml, so this blog is also about how to use TinyXML to read XML files.

TinyXML is a free and open source of C + + library, can be downloaded to the official web: https://sourceforge.net/projects/tinyxml/.

After downloading and decompressing, you can see the following files:

I am in windows with vs to write C + +, according to @marchtea, just to open the Tinyxml.sln directly, but I still use a stupid way:

    • Copy tinystr.cpp, Tinyxml.cpp, Tinyxmlerror.cpp, Tinyxmlparser.cpp, Tinystr.h, tinyxml.h to the engineering directory;
    • Then add the header file reference: #include "tinystr.h" #include "tinyxml.h".

Next, let's share the way I read the Solomon benchmark in the VRP problem, which refer to the official tutorial from TinyXML, which has a "Doc" subfolder in the Downloaded folder, opens it, and has an HTML file called "Tutorial0." Open it to see a detailed tutorial.

Ok,now begins!

The XML file I want to read has the following format (enumerate only the parts):

<!--XML file to read-->

<?xml version= "1.0" encoding= "UTF-8" standalone= "yes"?>

<instance>

  <network>

    <nodes>

      <node id= "0" type= "0" >

        <cx>40.0</cx>

        <cy >50.0</cy>

      </node>

    <!--have n+1 such node-->

    </nodes>  

  </network >

  <requests>

    <request id= "1" node= "1" >

      <tw>

        <start>145</start >

        <end>175</end>

      </tw>

      <quantity>20.0</quantity>

      < service_time>10.0</service_time>

    </request>

    <!--There are n such request nodes-->

  </ Requests>

</instance>

Here's a little explanation of why the number of nodes nodes is one more than the requests node. This is because the nodes node includes a customer node (n) and a warehouse node (1), whereas the requests attribute belongs only to the customer node.

I read the data in the XML file into an array of class objects, each representing a node, and the class is defined as follows:

Customer.h

#ifndef _customer_h

#define _CUSTOMER_H

 

class customer{public

:

  Customer (int id=0 , float x=0, float y=0, float starttime=0, float endtime=0, float quantity=0, float servicetime=0);

  void setId (int id);  Sets the value of the member id

  void SetX (float x);  Sets the value of member x

  void sety (float y);  Set member Y's value

  void Setstarttime (float starttime);//Set member StartTime value

  void Setendtime (float endtime);   Sets the value of the member Endtime

  void setquantity (float quantity);  Sets the value of the member quantity

  void Setservicetime (float servicetime);//Set member Servicetime value

  void Show ()//Display Customer node information

private:

  int id;

  float x;

  float y;

  float StartTime;

  float Endtime;

  float quantity;

  float servicetime;

};

#endif

OK, now start to paste the Main.cpp code (Customer.cpp simpler, no paste)

Main.cpp #include "Customer.h" #include "tinystr.h" #include "tinyxml.h" #include <iostream> #include <vec

tor> #include <string> #include <stdlib.h> #include <iomanip> using namespace std;    static const int Num_of_customer = 51; Customer quantity static const char* FILENAME = "Rc101_050.xml";

  filename int main () {Vector<customer *> customerset (0);//customer set, each element is a pointer int i,j,k,count of the customer object;  int Temp1; Storage of integer data float temp2;  Storing floating-point data customer* Customer;

    Temporary customer node pointer for (i=0; i<num_of_customer; i++) {//First initialize customer set customer = new Customer ();

  Customerset.push_back (customer);  Tixmldocument doc (FILENAME); Read the XML file if (!doc). LoadFile ()) return-1;     Returns Tixmlhandle Hdoc (&doc) If the file cannot be read;      Hdoc is the object of &doc pointing tixmlelement* Pelem; Pointer to Element Pelem = Hdoc.firstchildelement (). Element ();    Point to root node Tixmlhandle hroot (Pelem); Hroot is the root node//read X,y, which is placed in the Network->nodes->node node Tixmlelement* Nodeelem = hroot.firstchild ("Network"). FirstChild ("Nodes"). FirstChild ("Node"). Element (); Node node count = 0 is currently pointed; The node to which the record was moved, and the information of that node was entered into the order of the customer for (Nodeelem; nodeelem; nodeelem = Nodeelem->nextsiblingelement ( ) {///Reading node node information customer = Customerset[count];//Current customer node, note that you cannot assign a value to a new object, or you will invoke the copy constructor tixmlhandle node (nodeel EM); tixmlelement* xelem = node Nodeelem point to. FirstChild ("CX"). Element (); CX-node tixmlelement* yelem = node. FirstChild ("Cy"). Element (); CY Node Nodeelem->queryintattribute ("id", &AMP;TEMP1);     

    Put the ID in the Temp1, the attribute value Read method Customer->setid (TEMP1);  Temp2 = Atof (Xelem->gettext ());

    Char Rotary float customer->setx (TEMP2);

    Temp2 = Atof (Yelem->gettext ());

    Customer->sety (TEMP2);

  count++; //Read the rest of the information tixmlelement* Requestelem = Hroot.firstchild ("Requests"). FirstChild ("Request"). Element ();

  Point to request node count = 1; for (Requestelem; requestelem; requestele)m = Requestelem->nextsiblingelement ()) {customer = Customerset[count]; Current customer node, note that you cannot assign a value to a new object, or you will invoke the copy constructor Tixmlhandle request (Requestelem); The pointer points to an object tixmlelement* Starttimeelem = Request. FirstChild ("TW"). FirstChild ("Start"). Element (); Start time tixmlelement* Endtimeelem = Request. FirstChild ("TW"). FirstChild ("End").   Element (); End time tixmlelement* Quantityelem = Request. FirstChild ("Quantity").        Element (); Quantity tixmlelement* Servicetimeelem = Request. FirstChild ("Service_time").     Element ();

    Service time//read each data separately Temp2 = Atof (Starttimeelem->gettext ()); 

    Customer->setstarttime (TEMP2);

    Temp2 = Atof (Endtimeelem->gettext ());

    Customer->setendtime (TEMP2);

    Temp2 = Atof (Quantityelem->gettext ());

    Customer->setquantity (TEMP2);

    Temp2 = Atof (Servicetimeelem->gettext ());

    Customer->setservicetime (TEMP2);

  count++; ///Output The Read information to the console COUT&LT;&LT;SETIOSFLags (Ios_base::left) &LT;&LT;SETW (6) << "id" &LT;&LT;SETW (6) << "X" &LT;&LT;SETW (6) << "Y" << SETW << "StartTime" &LT;&LT;SETW (a) << "Endtime" &LT;&LT;SETW (a) << "Quantity" &LT;&LT;SETW (14)

  << "Servicetime" <<endl;

    For (i=0 i<num_of_customer; i++) {CUSTOMER = Customerset[i];

  Customer->show ();

  System ("pause");

return 0; }

Before explaining the content of main.cpp, explain some data types (just personal understanding, welcome error Correction):

    • Tixmldocument: A file node that reads the contents of an XML file into a variable of that type
    • tixmlelement*: Pointer to Node
    • Tixmlhandle: an instance of a node, which is the object that tixmlelement points to
    • FirstChild ("NodeName"): first child node with name "NodeName"
    • Nextsiblingelement (): Next sibling node element, they have the same parent node
    • Queryintattribute ("AttributeName", &var): Assigning values of attributes of a node property named AttributeName to the VAR variable with the int type
    • GetText (): Gets the contents of the current node element, that is, the text contained in <node>text</node>

OK, with some of these simple knowledge accumulation, you can easily read the XML file, now intercept the part of the XML to explain:

<instance>

  <network>

    <nodes>

      <node id= "0" type= "0" >

        <cx>40.0</ cx>

        <cy>50.0</cy>

      </node>

    <!--have n+1 node-->

    </nodes> </network> .....

</instance>

In this section we will read the customer ID, coordinates x,y, into the customer object.

1. First we get the file node Hdoc, now we want to go into the root node "instance":

tixmlelement* Pelem;      Pointer to element

Pelem = Hdoc.firstchildelement (). Element (); Point to root node

tixmlhandle hroot (pelem);    Hroot is the root node

The root node "instance" is the first child node of the file node, so Pelem = Hdoc.firstchildelement (). Element () allows the pointer pelem to point to "instance", Hroot is the object that Pelem points to.

2. Now we need to go into the "node" node, traverse its sibling node, and read all the data into it. The following statement assigns pointers to the first "node" nodes to Nodeelem:

tixmlelement* Nodeelem = hroot.firstchild ("Network"). FirstChild ("Nodes"). FirstChild ("Node"). Element (); You are currently pointing to the node node

The ID value of the node is placed in the attribute "id" of the "Nodes" node:

Nodeelem->queryintattribute ("id", &TEMP1); Put the ID in the Temp1, the attribute value reading method

The values of the coordinates x and y are then placed in the contents of the "CX" and "Cy" of the node nodes, so we read:

tixmlelement* Xelem = node. FirstChild ("CX"). Element (); CX-node

temp2 = Atof (Xelem->gettext ());  Char to float

function atof in library <stdlib> to convert a char array to a floating-point number.

With 1, 22 steps, we've read the ID, x, y values of the first node nodes into the object, and then we just need to traverse all the sibling nodes:

for (Nodeelem; nodeelem; nodeelem = Nodeelem->nextsiblingelement ()) {

...

}

Read into the Requests node of the StartTime, Endtime, quantity, Servicetime equivalent method is the same, the details refer to the Main.cpp code.

The results of the operation are as follows:

Summarize:

In fact, the key to reading XML files is:

    • Move the pointer to the node in which you want to read the data;
    • If the property value is read, the Queryintattribute method is used to read directly;
    • If the contents of the node are read, the GetText () method is used to read;
    • Continuous data has sibling relationships, using the Nextsiblingelement () method to point to the next sibling node

Postscript:

This blog post only describes how to read XML files, and as to how to write XML files, please refer to the official tutorials of tinyxml, especially the special conscience.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.