VTD-XML 2.10 is now released under Java, C#, C and C++. It can be downloaded at
https://sourceforge.net/projects/vtd-xml/files/vtd-xml/ximpleware_2.10/. This release includes a number of new features and enhancement.
There are also a number of bugs fixed. Special thanks to Jozef Aerts, John Sillers, Chris Tornau and a number of other users for input and suggestions
Before 2.10, the C version of vtd-xml makes extensive use of global variables for XPath query compilation. The thread safety problem arises when multple instances of an application perform XPath compilation at the same time. To resolve this issue, VTD-XML 2.10 replaces all global variables for XPath compilation with thread local vriables: instead of simply declaring a variable, prepend _thread to the declaration. The thread local variable is just like global variable, except it is specific/visible within a thread. The macro for "_thread" is defined in "customTypes.h."
How does the use of thread local variable impact the overall design of your application? Fortunately, very little change is required. The most significant one is the global thread context declaration: The old one looks something like this:
struct exception_context the_exception_context[1]; int main(){ exception e; Try { // put the code throwing exceptions here } Catch (e) { // handle exception in here } }
From 2.10 and onward the app will look like below
_thread struct exception_context the_exception_context[1]; int main(){ exception e; Try { // put the code throwing exceptions here } Catch (e) { // handle exception in here } }
Before version 2.10, the location cache depth is set to 3. In this version, you can choose either 3 or 5, by simply calling VTDGen's setLcDepth() (see the example below). The benefit is that at the cost of negligible parsing and memory overhead, the random access performance of VTDNav improves, especially for depth XML documents.
VTDGen vg = new VTDGen(); vg.selectLcDepth(5);
In this release, you now have the ability to insert text into an empty element (e.g. <a/>).
Below is a simple app written in VTD-XML and C++. #include "everything.h" //#include "bookMark.h" using namespace com_ximpleware; int main(){ FILE *f = NULL; FILE *fo = NULL; int i = 0; Long l = 0; int len = 0; int offset = 0; char* filename = "c:/xml/soap2.xml"; struct stat s; UByte *xml = NULL; // this is the buffer containing the XML content, UByte means unsigned byte //VTDGen *vg = NULL; // This is the VTDGen that parses XML VTDNav *vn = NULL; // This is the VTDNav that navigates the VTD records AutoPilot *ap = NULL; char *sm = "\n================\n"; // allocate a piece of buffer then reads in the document content // assume "c:\soap2.xml" is the name of the file f = fopen(filename,"r"); fo = fopen("c:/xml/out.txt","w"); stat(filename,&s); i = (int) s.st_size; printf("size of the file is %d \n",i); xml = new UByte[i]; fread(xml,sizeof(UByte),i,f); VTDGen vg; try{ vg.setDoc(xml,i); vg.parse(true); vn = vg.getNav(); AutoPilot ap; ap.declareXPathNameSpace(L"ns1",L"<a href="http://www.w3.org/2003/05/soap-envelope">http://www.w3.org/2003/05/soap-envelope</a>"); //if (ap.selectXPath(L"/ns1:Envelope/ns1:Header/*[@ns1:mustUnderstand]")){ if (ap.selectXPath(L"/ns1:Envelope/ns1:Header/*[@ns1:mustUnderstand]")){ //if (ap.selectXPath(L"/a/b/*")){ ap.printExprString(); ap.bind(vn); int i=-1; while((i=ap.evalXPath())!= -1){ //printf("\n hi ==> %d \n",i); l = vn->getElementFragment(); offset = (int) l; len = (int) (l>>32); fwrite((char *)(xml+offset),sizeof(UByte),len,fo); fwrite((char *) sm,sizeof(UByte),strlen((char*)sm),fo); } } fclose(f); fclose(fo); // remember C has no automatic garbage collector // needs to deallocate manually. delete(vn); } catch (ParseException &e){ //vg.printLineNumber(); printf(" error ===> %s \n",e.getMessage()); } catch (...) { delete (vn); } return 0; }