10 #include <sec_api/string_s.h>
13 #include <libxml/tree.h>
14 #include <libxml/parser.h>
15 #include <libxml/xpath.h>
16 #include <libxml/xpathInternals.h>
18 #include "include/priv_xml.h"
42 static void *xml_has_init_parser = NULL;
47 struct xml_buffer *xb = data;
51 static void free_xmlsearch(
void *data) {
58 static void free_parser(
void *data) {
62 static void free_xmlnode(
void *data) {
69 free((
char *)ninfo->
name);
72 free((
char *)ninfo->
key);
75 free((
char *)ninfo->
value);
79 static void free_xmldata(
void *data) {
82 if (xmldata->xpathCtx) {
83 xmlXPathFreeContext(xmldata->xpathCtx);
86 xmlFreeDoc(xmldata->doc);
88 if (xmldata->ValidCtxt) {
89 xmlFreeValidCtxt(xmldata->ValidCtxt);
94 static int32_t node_hash(
const void *data,
int key) {
97 const char *hashkey = (
key) ? data : ni->
key;
100 ret =
jenhash(hashkey, strlen(hashkey), 0);
102 ret =
jenhash(ni,
sizeof(ni), 0);
107 static int32_t attr_hash(
const void *data,
int key) {
110 const char *hashkey = (key) ? data : ai->
name;
112 ret =
jenhash(hashkey, strlen(hashkey), 0);
117 static struct xml_doc *xml_setup_parse(
struct xml_doc *xmldata,
int validate) {
119 if (!(xmldata->ValidCtxt = xmlNewValidCtxt())) {
123 if (!xmlValidateDocument(xmldata->ValidCtxt, xmldata->doc)) {
130 if (!(xmldata->root = xmlDocGetRootElement(xmldata->doc))) {
135 if (!(xmldata->xpathCtx = xmlXPathNewContext(xmldata->doc))) {
151 if (!(xmldata =
objalloc(
sizeof(*xmldata), free_xmldata))) {
155 if (!(xmldata->doc = xmlParseFile(docfile))) {
160 return xml_setup_parse(xmldata, validate);
174 if (!(xmldata =
objalloc(
sizeof(*xmldata), free_xmldata))) {
179 flags = XML_PARSE_DTDLOAD | XML_PARSE_DTDVALID;
181 flags = XML_PARSE_DTDVALID;
184 if (!(xmldata->doc = xmlReadMemory((
const char *)buffer, len, NULL, NULL, flags))) {
188 return xml_setup_parse(xmldata, 0);
191 static struct xml_node *xml_nodetohash(
struct xml_doc *xmldoc, xmlNodePtr node,
const char *attrkey) {
197 if (!(ninfo =
objalloc(
sizeof(*ninfo), free_xmlnode))) {
208 xmlstr = xmlNodeListGetString(xmldoc->doc, node->xmlChildrenNode, 1);
213 attrs = node->properties;
214 while(attrs && attrs->name && attrs->children) {
215 if (!(ainfo =
objalloc(
sizeof(*ainfo), NULL))) {
220 xmlstr = xmlNodeListGetString(xmldoc->doc, attrs->children, 1);
222 if (attrkey && !strcmp((
const char *)attrs->name, (
const char *)attrkey)) {
230 if (!attrkey && ninfo->
value) {
236 static struct xml_node *xml_gethash(
struct xml_search *xpsearch,
int i,
const char *attrkey) {
238 xmlNodeSetPtr nodeset;
247 if (!(nodeset = xpsearch->
xpathObj->nodesetval)) {
254 if (!(node = nodeset->nodeTab[i])) {
260 xn = xml_nodetohash(xpsearch->
xmldoc, node, attrkey);
268 static void free_iter(
void *data) {
280 rn = xml_nodetohash(xmldoc, xmldoc->root, NULL);
304 newiter =
objalloc(
sizeof(*newiter), free_iter);
314 xn = xml_gethash(xpsearch, 0, NULL);
363 for(i=0; i < cnt; i++) {
364 ninfo = xml_gethash(xpsearch, i, attrkey);
384 if (!
objref(xmldata) || !(xpsearch =
objalloc(
sizeof(*xpsearch), free_xmlsearch))) {
389 xpsearch->
xmldoc = xmldata;
390 if (!(xpsearch->
xpathObj = xmlXPathEvalExpression((
const xmlChar *)xpath, xmldata->xpathCtx))) {
396 if (xmlXPathNodeSetIsEmpty(xpsearch->
xpathObj->nodesetval)) {
403 if (!(xpsearch->
nodes = xml_setnodes(xpsearch, attrkey))) {
414 xmlNodeSetPtr nodeset;
416 if (xsearch && xsearch->
xpathObj && ((nodeset = xsearch->
xpathObj->nodesetval))) {
417 return nodeset->nodeNr;
460 return (
const char *)xmldoc->root->name;
475 encval = xmlEncodeSpecialChars(xmldoc->doc, (
const xmlChar *)value);
476 xmlNodeSetContent(node, encval);
478 encval = xmlNodeListGetString(xmldoc->doc, node->xmlChildrenNode, 1);
482 free((
void*)xnode->
value);
497 encval = xmlEncodeSpecialChars(xmldoc->doc, (
const xmlChar *)value);
498 xmlSetProp(xnode->
nodeptr, (
const xmlChar *)name, (
const xmlChar *)encval);
509 xmlXPathObjectPtr xpathObj;
510 char *lpath, *tok, *save, *cpath, *dup;
511 const char *root = (
char *)xmldoc->root->
name;
519 if (!(dup = strdup(xpath))) {
524 len = strlen(xpath)+1;
525 if (!(cpath = malloc(len))) {
530 if (!(lpath = malloc(len))) {
541 for (tok = strtok_r(dup,
"/", &save); tok ; tok = strtok_r(NULL,
"/", &save)) {
543 for (tok = strtok_s(dup,
"/", &save); tok ; tok = strtok_s(NULL,
"/", &save)) {
547 if (!strcmp(tok, root)) {
554 if (!(xpathObj = xmlXPathEvalExpression((
const xmlChar *)cpath, xmldoc->xpathCtx))) {
564 if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
565 nn =
xml_addnode(xmldoc, lpath, tok, NULL, NULL, NULL);
569 xmlXPathFreeObject(xpathObj);
581 static xmlNodePtr xml_getparent(
struct xml_doc *xmldoc,
const char *xpath) {
582 xmlXPathObjectPtr xpathObj;
583 xmlNodePtr parent = NULL;
587 if (!(xpathObj = xmlXPathEvalExpression((
const xmlChar *)xpath, xmldoc->xpathCtx))) {
591 if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
592 xmlXPathFreeObject(xpathObj);
596 if (!(nodes = xpathObj->nodesetval)) {
597 xmlXPathFreeObject(xpathObj);
602 for(i=cnt - 1; i >= 0; i--) {
603 if (nodes->nodeTab[i]->type == XML_ELEMENT_NODE) {
604 parent=nodes->nodeTab[i];
605 nodes->nodeTab[i] = NULL;
611 xmlXPathFreeObject(xpathObj);
615 xmlXPathFreeObject(xpathObj);
633 if (!(parent = xml_getparent(xmldoc, xpath))) {
638 xmlAddChild(parent,child->
nodeptr);
652 const char *attrkey,
const char *keyval) {
663 if (!(parent = xml_getparent(xmldoc, xpath))) {
669 encval = xmlEncodeSpecialChars(xmldoc->doc, (
const xmlChar *)value);
670 child = xmlNewDocNode(xmldoc->doc, NULL, (
const xmlChar *)name, encval);
672 xmlAddChild(parent,child);
674 if (attrkey && keyval) {
675 encval = xmlEncodeSpecialChars(xmldoc->doc, (
const xmlChar *)keyval);
676 xmlSetProp(child, (
const xmlChar *)attrkey, (
const xmlChar *)encval);
681 if (!(newnode = xml_nodetohash(xmldoc, child, attrkey))) {
713 struct xml_buffer *xb = buffer;
718 return (
char *)xb->buffer;
727 struct xml_buffer *xmlbuf;
734 xmlDocDumpFormatMemory(xmldoc->doc, &xmlbuf->buffer, &xmlbuf->size, 1);
743 if (!xml_has_init_parser) {
744 xml_has_init_parser =
objalloc(0, free_parser);
747 xmlKeepBlanksDefault(0);
748 xmlLoadExtDtdDefaultValue = 1;
749 xmlSubstituteEntitiesDefault(1);
751 objref(xml_has_init_parser);
759 if (xml_has_init_parser) {
771 xmlSetDocCompressMode(xmldoc->doc, compress);
772 xmlSaveFormatFile(file, xmldoc->doc, format);
773 xmlSetDocCompressMode(xmldoc->doc, 0);
void xml_modify(struct xml_doc *xmldoc, struct xml_node *xnode, const char *value)
Modify a XML node.
void * create_bucketlist(int bitmask, blisthash hash_function)
const char * key
Attribute key for searching and indexing.
int curpos
current position.
int objref(void *data)
Reference a object.
struct xml_node * xml_getnextnode(void *iter)
Return the next node.
struct xml_doc xml_doc
Forward decleration of structure.
int cnt
number of nodes in search path.
Iterator to traverse nodes in a xpath.
struct xml_node * xml_getrootnode(struct xml_doc *xmldoc)
Return reference to the root node.
void xml_unlink(struct xml_node *xnode)
Unlink a node from the document.
int objlock(void *data)
Lock the reference.
const char * name
Name of the node.
struct xml_node * xml_addnode(struct xml_doc *xmldoc, const char *xpath, const char *name, const char *value, const char *attrkey, const char *keyval)
Append a node to a path.
void xml_createpath(struct xml_doc *xmldoc, const char *xpath)
Create a path in XML document.
XML attribute name value pair.
struct xml_doc * xml_loadbuf(const uint8_t *buffer, uint32_t len, int validate)
Load a buffer into XML document returning refereence.
struct bucket_list * attrs
Bucket list of attributes.
struct xml_node * xml_getnode(struct xml_search *xsearch, const char *key)
Return a node in the search matching key.
void * objalloc(int size, objdestroy)
Allocate a referenced lockable object.
struct xml_doc * xml_loaddoc(const char *docfile, int validate)
Load a XML file into XML document and return reference.
void xml_free_buffer(void *data)
Reference destructor for xml_buffer.
struct xml_search * xsearch
Reference to search returned from xml_search()
void xml_appendnode(struct xml_doc *xmldoc, const char *xpath, struct xml_node *child)
Append a node to a path.
const char * xml_getattr(struct xml_node *xnode, const char *attr)
Return value of attribute.
void * xml_doctobuffer(struct xml_doc *xmldoc)
Return a dump of a XML document.
DTS Application library API Include file.
int xml_nodecount(struct xml_search *xsearch)
Return the number of nodes in the search path.
const char * name
Name of attribute.
const char * xml_getrootname(struct xml_doc *xmldoc)
Return the name of the root node.
struct xml_doc * xmldoc
Reference to XML document.
void xml_close()
Unreference the XML library.
const char * value
Value of the node.
struct bucket_list * nodes
Bucket list of all nodes.
int objunlock(void *data)
Unlock a reference.
void xml_init()
Initialise/Reference the XML library.
void xml_setattr(struct xml_doc *xmldoc, struct xml_node *xnode, const char *name, const char *value)
Modify a XML node attribute.
char * xml_getbuffer(void *buffer)
Return the buffer of a xml_buffer structure.
struct xml_search * xml_xpath(struct xml_doc *xmldata, const char *xpath, const char *attrkey)
Return a reference to a xpath search result.
void * nodeptr
Internal libxml2 node pointer.
void xml_delete(struct xml_node *xnode)
Delete a node from document it is not unrefd and should be.
#define jenhash(key, length, initval)
Define jenhash as hashlittle on big endian it should be hashbig.
const char * value
Value of attribute.
#define ALLOC_CONST(const_var, val)
Macro to assign values to char const.
int addtobucket(struct bucket_list *blist, void *data)
Add a reference to the bucketlist.
void * bucket_list_find_key(struct bucket_list *list, const void *key)
Find and return a reference to a item matching supplied key.
xmlXPathObjectPtr xpathObj
Xpath object.
int objunref(void *data)
Drop reference held.
struct xml_node * xml_getfirstnode(struct xml_search *xpsearch, void **iter)
Return reference to the first node optionally creating a iterator.
void xml_savefile(struct xml_doc *xmldoc, const char *file, int format, int compress)
Save XML document to a file.
Bucket list, hold hashed objects in buckets.
struct bucket_list * xml_getnodes(struct xml_search *xpsearch)
Return reference to bucket list containing nodes.