Performing Unified DOM Operations
At this point the XML DOM functions can operate on the document node in exactly the same way as if it were parsed from a file. The Xml* APIs are identical and thus your code can be portable for the actual application logic you need to perform. In the following update example, you use both XmlDom* and XmlXPath* functions to find the node and update it with the data passed in on the command line:
/*--------------------------------------------------------*/
/* Test XML unified C XML APIs----------------------------*/
/*--------------------------------------------------------*/
sword update_xml(xctx, doc, xpathexpr, value)
xmlctx *xctx;
xmldocnode *doc;
OraText *xpathexpr;
OraText *value;
{
xpctx *xpathctx = (xpctx *) 0;
OraText *baseuri = (OraText *) 0;
ub2 ctxpos = 1;
ub2 ctxsize = 1;
xpexpr *exprtree = (xpexpr *) 0;
xpobj *xpathobj = (xpobj *) 0;
xmlerr xerr = (xmlerr)0;
boolean nodes_exists = 0;
xmlnode *foo, *foobar;
/* print out the xml doc before updating it */
printf("\nThe xml instance before updating with the unified APIs:\n");
XmlSaveDom(xctx, &xerr, (xmlnode *)doc, "stdio", stdout, NULL);
/* create an XPath context */
xpathctx = XmlXPathCreateCtx(xctx, baseuri, (xmlnode *)doc,
ctxpos, ctxsize);
/* parse XPath expression */
exprtree = XmlXPathParse((xpctx *)xpathctx, (OraText *)xpathexpr,
(xmlerr)&xerr);
/* evaluate XPath expression */
xpathobj = XmlXPathEval((xpctx *)xpathctx, (xpexpr *)exprtree,
(xmlerr *)&xerr);
foobar = XmlXPathGetObjectNSetNode(xpathobj, 0);
foo = XmlDomGetFirstChild(xctx, foobar);
XmlDomSetNodeValue(xctx, foo, (oratext *)value);
printf("\nThe xml instance after updating with the unified APIs:\n");
XmlSaveDom(xctx, &xerr, (xmlnode *)doc, "stdio", stdout, NULL);
return OCI_SUCCESS;
}
XML_ERRMSG_F(tkpgerr, ectx, msg, err)
{
if (err)
{
printf("Error: %d\n", (int)err);
printf("%s\n", msg);
}
}
To demonstrate that the XML is actually updated, the function initially prints the XML document as it was received from the database query. It then must find the node that needs updating. This could be found by walking the DOM tree, but that can be tedious because it requires many lines of code. Instead, you can make use of XmlXpath functions to have the search done for you. XmlXpathParse() converts the XPath string into an expression form, which can then be passed to XmlPathEval() to actually find the node. Now you can call XmlXPathGetObjectNSetNode() to return the node, traverse to the first child, which is the text node, and perform the update with XmlDomGetFirstChild() and XmlDomSetNodeValue().At this point you have an updated XOB and need to send it on its way. In update_xml(), the XmlSaveDom() function is called to send it to standard I/O. It just as easily could have been saved as a file or saved back to the database with another OCI SQL statement.