The project under the original Windows platform used the MSXML component to access the Web Service interface, and later switched to Gsoap+tinyxml (Tinyxpath) to perform the required functions on a Linux platform because of Cross-platform needs. The use of Tinyxpath or encountered a number of problems, summed up.
Here to explain the Tinyxpath is Tinyxml+xpath, download Tinyxpath package will contain the original TinyXML file.
1. Use XPath to get XML child nodes
The XPath supported by Tinyxpath is incomplete and lacks documentation, trying to try it out all day and write the results directly.
1.) node naming case-independent matching
Here you use the name function and the Translate function, first convert all the node names to uppercase, and then compare them. The syntax is as follows:
*[translate (Name (), ' abcdefghijklmnopqrstuvwxyz ', ' abcdefghijklmnopqrstuvwxyz ') = ' XXXX ']
The name function returns the names of the nodes, and the translate function converts to uppercase.
2.) Node content comparison
The text function returns the contents of the node, the syntax
*[text () = ' XXXX ']
3.) Select Fixed Location node
The position function specifies the first few nodes, and the syntax is:
*[position () =xxx], here is the number type
For example, we will select the node name AAA, the second node of BBB, and the XPath should be renamed:
*[translate (Name (), ' abcdefghijklmnopqrstuvwxyz ', ' abcdefghijklmnopqrstuvwxyz ') = ' AAA ' and text () = ' BBB ' and position ( ) =2]
There is also a query efficiency issue, and it is not certain that putting position () =2 conditions at the front is not going to improve efficiency. The above can be encapsulated into a function:
Inline string Getnodexpath (const string & Strnodename, String strtext= "", String Pos= "")
{
String Strval;
Strval + = "*[";
Strval + + "translate" (Name (), ' abcdefghijklmnopqrstuvwxyz ', ' abcdefghijklmnopqrstuvwxyz ') = ' + strnode name + ' ';
if (!strtext.empty ())
Strval + = "and text () = '" +strtext+ "";
if (!pos.empty ())
Strval + = "and position () =" +POS;
Strval + = "]";
return strval;
}
#define Node (node) getnode (node)
#define NODE_AT (Node,pos) getnode (NODE, "", POS)
4.) Query node that satisfies certain conditions for child nodes
Without seeing the tinyxpath provided directly to get the contents of the child nodes, here we use the workaround, that is, to first determine the child node conditions and then use the parent keyword to specify the return parent node, define the Has_child macro
#define Has_child (Node,txt) string (String ("/") +getnode (node,txt) +string ("/parent::*"))
As an example:
String strXPath;
Strxpath= "/" + node ("XMLDATA") + "/" + node ("RATES");
strxpath+= "/" + NODE ("Reporatevo") +has_child ("Termbyyear", Mstrtype) +has_child ("Contractdate", Mstrsubtype);
strxpath+= "/" + NODE ("RATE");
Multiple has_child are in a juxtaposition relationship.
Here is the code snippet to get the node:
Tixmldocument Xdoc;
Xdoc. Parse (Wsresponse.c_str ());
if (Xdoc. Error ())
{
return 3;
}
Const tixmlelement * Xmain=xdoc. RootElement ();
Tinyxpath::xpath_processor Xproc (Xmain,xpath.c_str ());
unsigned nodecount =xproc.u_compute_xpath_node_set ();
if (nodecount==0)
{
return 4;
}
Tixmlnode * XNode = Xproc. Xnp_get_xpath_node (0);
2. Child node Content read
Tixmlprinter provides a way to get the content of a node to memory,
The code is as follows:
Tixmlprinter printer;
Xchild->accept (&printer);
Strres = printer. CStr ();
Here is a problem, when printing '/n ' returns, the saved string will be a space, '/r/n ' is the return line.
To sum up here, I hope to be helpful to the people who use Tinyxpath.