Asterisk - The Open Source Telephony Project  GIT-master-a24979a
xml.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2008, Eliel C. Sardanons (LU1ALY) <eliels@gmail.com>
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16 
17 /*! \file
18  *
19  * \brief XML abstraction layer
20  *
21  * \author Eliel C. Sardanons (LU1ALY) <eliels@gmail.com>
22  */
23 
24 /*** MODULEINFO
25  <support_level>core</support_level>
26  ***/
27 
28 #include "asterisk.h"
29 #include "asterisk/xml.h"
30 #include "asterisk/logger.h"
31 #include "asterisk/utils.h"
32 #include "asterisk/autoconfig.h"
33 
34 #if defined(HAVE_LIBXML2)
35 #include <libxml/parser.h>
36 #include <libxml/tree.h>
37 #include <libxml/xinclude.h>
38 #include <libxml/xpath.h>
39 #include <libxml/xpathInternals.h>
40 /* libxml2 ast_xml implementation. */
41 #ifdef HAVE_LIBXSLT
42  #include <libxslt/xsltInternals.h>
43  #include <libxslt/transform.h>
44  #include <libxslt/xsltutils.h>
45 #endif /* HAVE_LIBXSLT */
46 
47 
48 int ast_xml_init(void)
49 {
50  LIBXML_TEST_VERSION
51 #ifdef HAVE_LIBXSLT
52  xsltInit();
53 #endif
54  return 0;
55 }
56 
57 int ast_xml_finish(void)
58 {
59  xmlCleanupParser();
60 #ifdef HAVE_LIBXSLT
61 #ifdef HAVE_LIBXSLT_CLEANUP
62  xsltCleanupGlobals();
63 #else
64  xsltUninit();
65 #endif
66 #endif
67 
68  return 0;
69 }
70 
71 struct ast_xml_doc *ast_xml_open(char *filename)
72 {
73  xmlDoc *doc;
74 
75  if (!filename) {
76  return NULL;
77  }
78 
79  xmlSubstituteEntitiesDefault(1);
80 
81  doc = xmlReadFile(filename, NULL, XML_PARSE_RECOVER);
82  if (!doc) {
83  return NULL;
84  }
85 
86  /* process xinclude elements. */
87  if (xmlXIncludeProcess(doc) < 0) {
88  xmlFreeDoc(doc);
89  return NULL;
90  }
91 
92 #ifdef HAVE_LIBXSLT
93  {
94  xsltStylesheetPtr xslt = xsltLoadStylesheetPI(doc);
95  if (xslt) {
96  xmlDocPtr tmpdoc = xsltApplyStylesheet(xslt, doc, NULL);
97  xsltFreeStylesheet(xslt);
98  xmlFreeDoc(doc);
99  if (!tmpdoc) {
100  return NULL;
101  }
102  doc = tmpdoc;
103  }
104  }
105 #else /* no HAVE_LIBXSLT */
106  ast_log(LOG_NOTICE, "XSLT support not found. XML documentation may be incomplete.\n");
107 #endif /* HAVE_LIBXSLT */
108 
109  /* Optimize for XPath */
110  xmlXPathOrderDocElems(doc);
111 
112  return (struct ast_xml_doc *) doc;
113 }
114 
115 struct ast_xml_doc *ast_xml_new(void)
116 {
117  xmlDoc *doc;
118 
119  doc = xmlNewDoc((const xmlChar *) "1.0");
120  return (struct ast_xml_doc *) doc;
121 }
122 
123 struct ast_xml_node *ast_xml_new_node(const char *name)
124 {
125  xmlNode *node;
126  if (!name) {
127  return NULL;
128  }
129 
130  node = xmlNewNode(NULL, (const xmlChar *) name);
131 
132  return (struct ast_xml_node *) node;
133 }
134 
135 struct ast_xml_node *ast_xml_new_child(struct ast_xml_node *parent, const char *child_name)
136 {
137  xmlNode *child;
138 
139  if (!parent || !child_name) {
140  return NULL;
141  }
142 
143  child = xmlNewChild((xmlNode *) parent, NULL, (const xmlChar *) child_name, NULL);
144  return (struct ast_xml_node *) child;
145 }
146 
147 struct ast_xml_node *ast_xml_add_child(struct ast_xml_node *parent, struct ast_xml_node *child)
148 {
149  if (!parent || !child) {
150  return NULL;
151  }
152  return (struct ast_xml_node *) xmlAddChild((xmlNode *) parent, (xmlNode *) child);
153 }
154 
155 struct ast_xml_node *ast_xml_add_child_list(struct ast_xml_node *parent, struct ast_xml_node *child)
156 {
157  if (!parent || !child) {
158  return NULL;
159  }
160  return (struct ast_xml_node *) xmlAddChildList((xmlNode *) parent, (xmlNode *) child);
161 }
162 
163 struct ast_xml_node *ast_xml_copy_node_list(struct ast_xml_node *list)
164 {
165  if (!list) {
166  return NULL;
167  }
168  return (struct ast_xml_node *) xmlCopyNodeList((xmlNode *) list);
169 }
170 
171 struct ast_xml_doc *ast_xml_read_memory(char *buffer, size_t size)
172 {
173  xmlDoc *doc;
174 
175  if (!buffer) {
176  return NULL;
177  }
178 
179  if (!(doc = xmlParseMemory(buffer, (int) size))) {
180  /* process xinclude elements. */
181  if (xmlXIncludeProcess(doc) < 0) {
182  xmlFreeDoc(doc);
183  return NULL;
184  }
185  }
186 
187  return (struct ast_xml_doc *) doc;
188 }
189 
190 void ast_xml_close(struct ast_xml_doc *doc)
191 {
192  if (!doc) {
193  return;
194  }
195 
196  xmlFreeDoc((xmlDoc *) doc);
197  doc = NULL;
198 }
199 
200 void ast_xml_set_root(struct ast_xml_doc *doc, struct ast_xml_node *node)
201 {
202  if (!doc || !node) {
203  return;
204  }
205 
206  xmlDocSetRootElement((xmlDoc *) doc, (xmlNode *) node);
207 }
208 
209 struct ast_xml_node *ast_xml_get_root(struct ast_xml_doc *doc)
210 {
211  xmlNode *root_node;
212 
213  if (!doc) {
214  return NULL;
215  }
216 
217  root_node = xmlDocGetRootElement((xmlDoc *) doc);
218 
219  return (struct ast_xml_node *) root_node;
220 }
221 
222 void ast_xml_free_node(struct ast_xml_node *node)
223 {
224  if (!node) {
225  return;
226  }
227 
228  xmlFreeNode((xmlNode *) node);
229  node = NULL;
230 }
231 
232 void ast_xml_free_attr(const char *attribute)
233 {
234  if (attribute) {
235  xmlFree((char *) attribute);
236  }
237 }
238 
239 void ast_xml_free_text(const char *text)
240 {
241  if (text) {
242  xmlFree((char *) text);
243  }
244 }
245 
246 const char *ast_xml_get_attribute(struct ast_xml_node *node, const char *attrname)
247 {
248  xmlChar *attrvalue;
249 
250  if (!node) {
251  return NULL;
252  }
253 
254  if (!attrname) {
255  return NULL;
256  }
257 
258  attrvalue = xmlGetProp((xmlNode *) node, (xmlChar *) attrname);
259 
260  return (const char *) attrvalue;
261 }
262 
263 int ast_xml_set_attribute(struct ast_xml_node *node, const char *name, const char *value)
264 {
265  if (!name || !value) {
266  return -1;
267  }
268 
269  if (!xmlSetProp((xmlNode *) node, (xmlChar *) name, (xmlChar *) value)) {
270  return -1;
271  }
272 
273  return 0;
274 }
275 
276 struct ast_xml_node *ast_xml_find_element(struct ast_xml_node *root_node, const char *name, const char *attrname, const char *attrvalue)
277 {
278  struct ast_xml_node *cur;
279  const char *attr;
280 
281  if (!root_node) {
282  return NULL;
283  }
284 
285  for (cur = root_node; cur; cur = ast_xml_node_get_next(cur)) {
286  /* Check if the name matchs */
287  if (strcmp(ast_xml_node_get_name(cur), name)) {
288  continue;
289  }
290  /* We need to check for a specific attribute name? */
291  if (!attrname || !attrvalue) {
292  return cur;
293  }
294  /* Get the attribute, we need to compare it. */
295  if ((attr = ast_xml_get_attribute(cur, attrname))) {
296  /* does attribute name/value matches? */
297  if (!strcmp(attr, attrvalue)) {
298  ast_xml_free_attr(attr);
299  return cur;
300  }
301  ast_xml_free_attr(attr);
302  }
303  }
304 
305  return NULL;
306 }
307 
308 struct ast_xml_doc *ast_xml_get_doc(struct ast_xml_node *node)
309 {
310  if (!node) {
311  return NULL;
312  }
313 
314  return (struct ast_xml_doc *) ((xmlNode *)node)->doc;
315 }
316 
317 struct ast_xml_ns *ast_xml_find_namespace(struct ast_xml_doc *doc, struct ast_xml_node *node, const char *ns_name) {
318  xmlNsPtr ns = xmlSearchNs((xmlDocPtr) doc, (xmlNodePtr) node, (xmlChar *) ns_name);
319  return (struct ast_xml_ns *) ns;
320 }
321 
322 const char *ast_xml_get_ns_prefix(struct ast_xml_ns *ns)
323 {
324  return (const char *) ((xmlNsPtr) ns)->prefix;
325 }
326 
327 const char *ast_xml_get_ns_href(struct ast_xml_ns *ns)
328 {
329  return (const char *) ((xmlNsPtr) ns)->href;
330 }
331 
332 const char *ast_xml_get_text(struct ast_xml_node *node)
333 {
334  if (!node) {
335  return NULL;
336  }
337 
338  return (const char *) xmlNodeGetContent((xmlNode *) node);
339 }
340 
341 void ast_xml_set_text(struct ast_xml_node *node, const char *content)
342 {
343  if (!node || !content) {
344  return;
345  }
346 
347  xmlNodeSetContent((xmlNode *) node, (const xmlChar *) content);
348 }
349 
350 void ast_xml_set_name(struct ast_xml_node *node, const char *name)
351 {
352  if (!node || !name) {
353  return;
354  }
355 
356  xmlNodeSetName((xmlNode *) node, (const xmlChar *) name);
357 }
358 
359 int ast_xml_doc_dump_file(FILE *output, struct ast_xml_doc *doc)
360 {
361  return xmlDocDump(output, (xmlDocPtr)doc);
362 }
363 
364 const char *ast_xml_node_get_name(struct ast_xml_node *node)
365 {
366  return (const char *) ((xmlNode *) node)->name;
367 }
368 
369 struct ast_xml_node *ast_xml_node_get_children(struct ast_xml_node *node)
370 {
371  return (struct ast_xml_node *) ((xmlNode *) node)->children;
372 }
373 
374 struct ast_xml_node *ast_xml_node_get_next(struct ast_xml_node *node)
375 {
376  return (struct ast_xml_node *) ((xmlNode *) node)->next;
377 }
378 
379 struct ast_xml_node *ast_xml_node_get_prev(struct ast_xml_node *node)
380 {
381  return (struct ast_xml_node *) ((xmlNode *) node)->prev;
382 }
383 
384 struct ast_xml_node *ast_xml_node_get_parent(struct ast_xml_node *node)
385 {
386  return (struct ast_xml_node *) ((xmlNode *) node)->parent;
387 }
388 
389 struct ast_xml_node *ast_xml_xpath_get_first_result(struct ast_xml_xpath_results *results)
390 {
391  return (struct ast_xml_node *) ((xmlXPathObjectPtr) results)->nodesetval->nodeTab[0];
392 }
393 
394 struct ast_xml_node *ast_xml_xpath_get_result(struct ast_xml_xpath_results *results, int i)
395 {
396  return (struct ast_xml_node *) ((xmlXPathObjectPtr) results)->nodesetval->nodeTab[i];
397 }
398 
399 void ast_xml_xpath_results_free(struct ast_xml_xpath_results *results)
400 {
401  if (!results) {
402  return;
403  }
404  xmlXPathFreeObject((xmlXPathObjectPtr) results);
405 }
406 
407 int ast_xml_xpath_num_results(struct ast_xml_xpath_results *results)
408 {
409  if (!results) {
410  return 0;
411  }
412  return ((xmlXPathObjectPtr) results)->nodesetval->nodeNr;
413 }
414 
415 struct ast_xml_xpath_results *ast_xml_query(struct ast_xml_doc *doc, const char *xpath_str)
416 {
417  xmlXPathContextPtr context;
418  xmlXPathObjectPtr result;
419  if (!(context = xmlXPathNewContext((xmlDoc *) doc))) {
420  ast_log(LOG_ERROR, "Could not create XPath context!\n");
421  return NULL;
422  }
423  result = xmlXPathEvalExpression((xmlChar *) xpath_str, context);
424  xmlXPathFreeContext(context);
425  if (!result) {
426  ast_log(LOG_WARNING, "Error for query: %s\n", xpath_str);
427  return NULL;
428  }
429  if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
430  xmlXPathFreeObject(result);
431  ast_debug(5, "No results for query: %s\n", xpath_str);
432  return NULL;
433  }
434  return (struct ast_xml_xpath_results *) result;
435 }
436 
437 struct ast_xml_xpath_results *ast_xml_query_with_namespaces(struct ast_xml_doc *doc, const char *xpath_str,
438  struct ast_xml_namespace_def_vector *namespaces)
439 {
440  xmlXPathContextPtr context;
441  xmlXPathObjectPtr result;
442  int i;
443 
444  if (!(context = xmlXPathNewContext((xmlDoc *) doc))) {
445  ast_log(LOG_ERROR, "Could not create XPath context!\n");
446  return NULL;
447  }
448 
449  for (i = 0; i < AST_VECTOR_SIZE(namespaces); i++) {
450  struct ast_xml_namespace_def ns = AST_VECTOR_GET(namespaces, i);
451  if (xmlXPathRegisterNs(context, (xmlChar *)ns.prefix,
452  (xmlChar *)ns.href) != 0) {
453  xmlXPathFreeContext(context);
454  ast_log(LOG_ERROR, "Could not register namespace %s:%s\n",
455  ns.prefix, ns.href);
456  return NULL;
457  }
458  }
459 
460  result = xmlXPathEvalExpression((xmlChar *) xpath_str, context);
461  xmlXPathFreeContext(context);
462  if (!result) {
463  ast_log(LOG_WARNING, "Error for query: %s\n", xpath_str);
464  return NULL;
465  }
466  if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
467  xmlXPathFreeObject(result);
468  ast_debug(5, "No results for query: %s\n", xpath_str);
469  return NULL;
470  }
471  return (struct ast_xml_xpath_results *) result;
472 }
473 
474 #ifdef HAVE_LIBXSLT
475 struct ast_xslt_doc *ast_xslt_open(char *filename)
476 {
477  xsltStylesheet *xslt;
478  xmlDoc *xml;
479 
480  xmlSubstituteEntitiesDefault(1);
481 
482  xml = xmlReadFile(filename, NULL, XML_PARSE_RECOVER);
483  if (!xml) {
484  return NULL;
485  }
486 
487  if (xmlXIncludeProcess(xml) < 0) {
488  xmlFreeDoc(xml);
489  return NULL;
490  }
491  xmlXPathOrderDocElems(xml);
492 
493  if (!(xslt = xsltParseStylesheetDoc(xml))) {
494  xmlFreeDoc(xml);
495  return NULL;
496  }
497 
498  return (struct ast_xslt_doc *) xslt;
499 }
500 
501 struct ast_xslt_doc *ast_xslt_read_memory(char *buffer, size_t size)
502 {
503  xsltStylesheet *xslt;
504  xmlDoc *doc;
505 
506  if (!buffer) {
507  return NULL;
508  }
509 
510  xmlSubstituteEntitiesDefault(1);
511 
512  if (!(doc = xmlParseMemory(buffer, (int) size))) {
513  return NULL;
514  }
515 
516  if (xmlXIncludeProcess(doc) < 0) {
517  xmlFreeDoc(doc);
518  return NULL;
519  }
520 
521  if (!(xslt = xsltParseStylesheetDoc(doc))) {
522  xmlFreeDoc(doc);
523  return NULL;
524  }
525 
526  return (struct ast_xslt_doc *) xslt;
527 }
528 
529 void ast_xslt_close(struct ast_xslt_doc *axslt)
530 {
531  if (!axslt) {
532  return;
533  }
534 
535  xsltFreeStylesheet((xsltStylesheet *) axslt);
536 }
537 
538 struct ast_xml_doc *ast_xslt_apply(struct ast_xslt_doc *axslt, struct ast_xml_doc *axml, const char **params)
539 {
540  xsltStylesheet *xslt = (xsltStylesheet *)axslt;
541  xmlDoc *xml = (xmlDoc *)axml;
542  xsltTransformContextPtr ctxt;
543  xmlNs *ns;
544  xmlDoc *res;
545  int options = XSLT_PARSE_OPTIONS;
546 
547  /*
548  * Normally we could just call xsltApplyStylesheet() without creating
549  * our own transform context but we need to pass parameters to it
550  * that have namespace prefixes and that's not supported. Instead
551  * we have to create a transform context, iterate over the namespace
552  * declarations in the stylesheet (not the incoming xml document),
553  * and add them to the transform context's xpath context.
554  *
555  * The alternative would be to pass the parameters with namespaces
556  * as text strings but that's not intuitive and results in much
557  * slower performance than adding the namespaces here.
558  */
559  ctxt = xsltNewTransformContext(xslt, xml);
560  xsltSetCtxtParseOptions(ctxt, options);
561 
562  for (ns = xslt->doc->children->nsDef; ns; ns = ns->next) {
563  if (xmlXPathRegisterNs(ctxt->xpathCtxt, ns->prefix, ns->href) != 0) {
564  xmlXPathFreeContext(ctxt->xpathCtxt);
565  xsltFreeTransformContext(ctxt);
566  return NULL;
567  }
568  }
569 
570  res = xsltApplyStylesheetUser(xslt, xml, params, NULL, NULL, ctxt);
571 
572  return (struct ast_xml_doc *)res;
573 }
574 
575 int ast_xslt_save_result_to_string(char **buffer, int *length, struct ast_xml_doc *result,
576  struct ast_xslt_doc *axslt)
577 {
578  return xsltSaveResultToString((xmlChar **)buffer, length, (xmlDoc *)result, (xsltStylesheet *)axslt);
579 }
580 
581 #endif /* defined(HAVE_LIBXSLT) */
582 #endif /* defined(HAVE_LIBXML2) */
char * text
Definition: app_queue.c:1641
Asterisk main include file. File version handling, generic pbx functions.
#define ast_log
Definition: astobj2.c:42
static PGresult * result
Definition: cel_pgsql.c:84
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:120
static const char name[]
Definition: format_mp3.c:68
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_NOTICE
#define LOG_WARNING
#define NULL
Definition: resample.c:96
Namespace definition.
Definition: xml.h:301
const char * prefix
Definition: xml.h:302
const char * href
Definition: xml.h:303
Definition: test_heap.c:38
int value
Definition: syslog.c:37
static struct test_options options
Utility functions.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680
struct ast_xml_doc * ast_xml_new(void)
Create a XML document.
Definition: xml.c:115
const char * ast_xml_node_get_name(struct ast_xml_node *node)
Get the name of a node.
Definition: xml.c:364
struct ast_xml_node * ast_xml_xpath_get_first_result(struct ast_xml_xpath_results *results)
Return the first result node of an XPath query.
Definition: xml.c:389
struct ast_xml_doc * ast_xml_open(char *filename)
Open an XML document.
Definition: xml.c:71
struct ast_xml_doc * ast_xml_read_memory(char *buffer, size_t size)
Open an XML document that resides in memory.
Definition: xml.c:171
struct ast_xml_node * ast_xml_add_child_list(struct ast_xml_node *parent, struct ast_xml_node *child)
Add a list of child nodes, to a specified parent node.
Definition: xml.c:155
struct ast_xml_ns * ast_xml_find_namespace(struct ast_xml_doc *doc, struct ast_xml_node *node, const char *ns_name)
Definition: xml.c:317
struct ast_xml_node * ast_xml_node_get_children(struct ast_xml_node *node)
Get the node's children.
Definition: xml.c:369
struct ast_xml_node * ast_xml_new_node(const char *name)
Create a XML node.
Definition: xml.c:123
int ast_xml_xpath_num_results(struct ast_xml_xpath_results *results)
Return the number of results from an XPath query.
Definition: xml.c:407
struct ast_xml_node * ast_xml_new_child(struct ast_xml_node *parent, const char *child_name)
Add a child node inside a passed parent node.
Definition: xml.c:135
struct ast_xml_node * ast_xml_copy_node_list(struct ast_xml_node *list)
Create a copy of a n ode list.
Definition: xml.c:163
void ast_xml_close(struct ast_xml_doc *doc)
Close an already open document and free the used structure.
Definition: xml.c:190
struct ast_xml_node * ast_xml_find_element(struct ast_xml_node *root_node, const char *name, const char *attrname, const char *attrvalue)
Find a node element by name.
Definition: xml.c:276
int ast_xml_finish(void)
Cleanup library allocated global data.
Definition: xml.c:57
void ast_xml_free_attr(const char *attribute)
Free an attribute returned by ast_xml_get_attribute()
Definition: xml.c:232
struct ast_xml_node * ast_xml_node_get_parent(struct ast_xml_node *node)
Get the parent of a specified node.
Definition: xml.c:384
struct ast_xml_xpath_results * ast_xml_query(struct ast_xml_doc *doc, const char *xpath_str)
Execute an XPath query on an XML document.
Definition: xml.c:415
const char * ast_xml_get_ns_href(struct ast_xml_ns *ns)
Get the href of a namespace.
Definition: xml.c:327
struct ast_xml_node * ast_xml_add_child(struct ast_xml_node *parent, struct ast_xml_node *child)
Add a child node, to a specified parent node.
Definition: xml.c:147
const char * ast_xml_get_ns_prefix(struct ast_xml_ns *ns)
Get the prefix of a namespace.
Definition: xml.c:322
const char * ast_xml_get_attribute(struct ast_xml_node *node, const char *attrname)
Get a node attribute by name.
Definition: xml.c:246
struct ast_xml_node * ast_xml_node_get_next(struct ast_xml_node *node)
Get the next node in the same level.
Definition: xml.c:374
int ast_xml_doc_dump_file(FILE *output, struct ast_xml_doc *doc)
Dump the specified document to a file.
Definition: xml.c:359
struct ast_xml_doc * ast_xml_get_doc(struct ast_xml_node *node)
Get the document based on a node.
Definition: xml.c:308
struct ast_xml_node * ast_xml_node_get_prev(struct ast_xml_node *node)
Get the previous node in the same leve.
Definition: xml.c:379
struct ast_xml_node * ast_xml_xpath_get_result(struct ast_xml_xpath_results *results, int i)
Return a specific result node of an XPath query.
Definition: xml.c:394
void ast_xml_xpath_results_free(struct ast_xml_xpath_results *results)
Free the XPath results.
Definition: xml.c:399
int ast_xml_set_attribute(struct ast_xml_node *node, const char *name, const char *value)
Set an attribute to a node.
Definition: xml.c:263
void ast_xml_set_text(struct ast_xml_node *node, const char *content)
Set an element content string.
Definition: xml.c:341
const char * ast_xml_get_text(struct ast_xml_node *node)
Get an element content string.
Definition: xml.c:332
void ast_xml_free_text(const char *text)
Free a content element that was returned by ast_xml_get_text()
Definition: xml.c:239
int ast_xml_init(void)
Initialize the XML library implementation. This function is used to setup everything needed to start ...
Definition: xml.c:48
void ast_xml_set_root(struct ast_xml_doc *doc, struct ast_xml_node *node)
Specify the root node of a XML document.
Definition: xml.c:200
struct ast_xml_xpath_results * ast_xml_query_with_namespaces(struct ast_xml_doc *doc, const char *xpath_str, struct ast_xml_namespace_def_vector *namespaces)
Execute an XPath query on an XML document with namespaces.
Definition: xml.c:437
void ast_xml_set_name(struct ast_xml_node *node, const char *name)
Set or reset an element's name.
Definition: xml.c:350
void ast_xml_free_node(struct ast_xml_node *node)
Free node.
Definition: xml.c:222
struct ast_xml_node * ast_xml_get_root(struct ast_xml_doc *doc)
Get the document root node.
Definition: xml.c:209
Asterisk XML abstraction layer.