The XDK C++ XML APIs need an XML context from which to operate. When using the C APIs this is done by calling OCIXmlDbInitXmlCtx() and then casting its return context to xmlnode. This can’t be done directly in C++; therefore, the following function wraps the C one to produce a C++ context you can use with the C++ XDK APIs.
sb4 ociapi::select_from_doc(OCIXMLType* xml, text *xpathexpr){ boolean result = 0; OCIXMLType *newxml = (OCIXMLType *) 0; OCIXMLType *xmltran = (OCIXMLType *) 0; sword status = 0; /* For XML C++ APIs */ OCIDuration dur = OCI_DURATION_SESSION; struct xmlctx *xctx = (xmlctx *)0; xmldocnode *doc = (xmldocnode *)0; ocixmldbparam params[1]; /* Get an XML C and C++ context */ params[0].name_ocixmldbparam = XCTXINIT_OCIDUR; params[0].value_ocixmldbparam = &dur; xctx = OCIXmlDbInitXmlCtx( envhp, svchp, errhp, params, 1); CXmlCtx* cxctxp = new CXmlCtx( xctx); /* convert the xmltype value to C++ DocumentRef */ doc = (xmldocnode *) xml; DOMImplRef< CXmlCtx, xmlnode> impl_ref( cxctxp, new DOMImplementation< xmlnode>( FALSE)); DocumentRef< xmlnode>* doc_refp = impl_ref.formDocument( (xmlnode*)doc); /* test xml unified C APIs */ if (doXPath< CXmlCtx, xmlnode>( cxctxp, *doc_refp, (char*)xpathexpr)) { printf("FAILED: doXPath()\n"); return OCI_ERROR; } /* free the statement handle */ if (stmthp) { OCIHandleFree((dvoid *)stmthp, OCI_HTYPE_STMT); } /* free the xmlctx */ OCIXmlDbFreeXmlCtx(xctx); /* free xml instances using OCIObjectFree */ if (newxml && (status = OCIObjectFree(envhp, errhp, (dvoid *) newxml, (ub2)OCI_OBJECTFREE_FORCE))) { printf("FAILED: OCIObjectFree()\n"); checkerr(errhp, status); return OCI_ERROR; } return OCI_SUCCESS; }
The OCIXmlDbInit() function returns the C context, xctx, which is then passed to the CXmlCtx() constructor to return the C++ context, cxctxp. This context can then be used to create the C++ DocumentRef, doc_refp, that points to the XOB DOM and can be used with the C++ XDK APIs.