Asterisk - The Open Source Telephony Project  21.4.1
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 /*!
72  * \internal
73  * \brief Process XML Inclusions (XInclude).
74  *
75  * XIncludes can result in new includes being inserted, so we need to reprocess
76  * until no changes are made or we encounter an error.
77  *
78  * \param doc the document to process
79  *
80  * \retval 0 if XInclude processing concluded successfully
81  * \retval -1 if an error occurred during XInclude processing
82  */
83 static int process_xincludes(xmlDoc *doc)
84 {
85  int res;
86 
87  do {
88  res = xmlXIncludeProcess(doc);
89  } while (res > 0);
90 
91  return res;
92 }
93 
94 struct ast_xml_doc *ast_xml_open(char *filename)
95 {
96  xmlDoc *doc;
97 
98  if (!filename) {
99  return NULL;
100  }
101 
102  doc = xmlReadFile(filename, NULL, XML_PARSE_RECOVER | XML_PARSE_NOENT);
103  if (!doc) {
104  return NULL;
105  }
106 
107  /* process xinclude elements. */
108  if (process_xincludes(doc) < 0) {
109  xmlFreeDoc(doc);
110  return NULL;
111  }
112 
113 #ifdef HAVE_LIBXSLT
114  {
115  xsltStylesheetPtr xslt = xsltLoadStylesheetPI(doc);
116  if (xslt) {
117  xmlDocPtr tmpdoc = xsltApplyStylesheet(xslt, doc, NULL);
118  xsltFreeStylesheet(xslt);
119  xmlFreeDoc(doc);
120  if (!tmpdoc) {
121  return NULL;
122  }
123  doc = tmpdoc;
124  }
125  }
126 #else /* no HAVE_LIBXSLT */
127  ast_log(LOG_NOTICE, "XSLT support not found. XML documentation may be incomplete.\n");
128 #endif /* HAVE_LIBXSLT */
129 
130  /* Optimize for XPath */
131  xmlXPathOrderDocElems(doc);
132 
133  return (struct ast_xml_doc *) doc;
134 }
135 
136 struct ast_xml_doc *ast_xml_new(void)
137 {
138  xmlDoc *doc;
139 
140  doc = xmlNewDoc((const xmlChar *) "1.0");
141  return (struct ast_xml_doc *) doc;
142 }
143 
144 struct ast_xml_node *ast_xml_new_node(const char *name)
145 {
146  xmlNode *node;
147  if (!name) {
148  return NULL;
149  }
150 
151  node = xmlNewNode(NULL, (const xmlChar *) name);
152 
153  return (struct ast_xml_node *) node;
154 }
155 
156 struct ast_xml_node *ast_xml_new_child(struct ast_xml_node *parent, const char *child_name)
157 {
158  xmlNode *child;
159 
160  if (!parent || !child_name) {
161  return NULL;
162  }
163 
164  child = xmlNewChild((xmlNode *) parent, NULL, (const xmlChar *) child_name, NULL);
165  return (struct ast_xml_node *) child;
166 }
167 
168 struct ast_xml_node *ast_xml_add_child(struct ast_xml_node *parent, struct ast_xml_node *child)
169 {
170  if (!parent || !child) {
171  return NULL;
172  }
173  return (struct ast_xml_node *) xmlAddChild((xmlNode *) parent, (xmlNode *) child);
174 }
175 
176 struct ast_xml_node *ast_xml_add_child_list(struct ast_xml_node *parent, struct ast_xml_node *child)
177 {
178  if (!parent || !child) {
179  return NULL;
180  }
181  return (struct ast_xml_node *) xmlAddChildList((xmlNode *) parent, (xmlNode *) child);
182 }
183 
184 struct ast_xml_node *ast_xml_copy_node_list(struct ast_xml_node *list)
185 {
186  if (!list) {
187  return NULL;
188  }
189  return (struct ast_xml_node *) xmlCopyNodeList((xmlNode *) list);
190 }
191 
192 struct ast_xml_doc *ast_xml_read_memory(char *buffer, size_t size)
193 {
194  xmlDoc *doc;
195 
196  if (!buffer) {
197  return NULL;
198  }
199 
200  if (!(doc = xmlParseMemory(buffer, (int) size))) {
201  /* process xinclude elements. */
202  if (process_xincludes(doc) < 0) {
203  xmlFreeDoc(doc);
204  return NULL;
205  }
206  }
207 
208  return (struct ast_xml_doc *) doc;
209 }
210 
211 void ast_xml_close(struct ast_xml_doc *doc)
212 {
213  if (!doc) {
214  return;
215  }
216 
217  xmlFreeDoc((xmlDoc *) doc);
218  doc = NULL;
219 }
220 
221 void ast_xml_set_root(struct ast_xml_doc *doc, struct ast_xml_node *node)
222 {
223  if (!doc || !node) {
224  return;
225  }
226 
227  xmlDocSetRootElement((xmlDoc *) doc, (xmlNode *) node);
228 }
229 
230 struct ast_xml_node *ast_xml_get_root(struct ast_xml_doc *doc)
231 {
232  xmlNode *root_node;
233 
234  if (!doc) {
235  return NULL;
236  }
237 
238  root_node = xmlDocGetRootElement((xmlDoc *) doc);
239 
240  return (struct ast_xml_node *) root_node;
241 }
242 
243 void ast_xml_free_node(struct ast_xml_node *node)
244 {
245  if (!node) {
246  return;
247  }
248 
249  xmlFreeNode((xmlNode *) node);
250  node = NULL;
251 }
252 
253 void ast_xml_free_attr(const char *attribute)
254 {
255  if (attribute) {
256  xmlFree((char *) attribute);
257  }
258 }
259 
260 void ast_xml_free_text(const char *text)
261 {
262  if (text) {
263  xmlFree((char *) text);
264  }
265 }
266 
267 const char *ast_xml_get_attribute(struct ast_xml_node *node, const char *attrname)
268 {
269  xmlChar *attrvalue;
270 
271  if (!node) {
272  return NULL;
273  }
274 
275  if (!attrname) {
276  return NULL;
277  }
278 
279  attrvalue = xmlGetProp((xmlNode *) node, (xmlChar *) attrname);
280 
281  return (const char *) attrvalue;
282 }
283 
284 int ast_xml_set_attribute(struct ast_xml_node *node, const char *name, const char *value)
285 {
286  if (!name || !value) {
287  return -1;
288  }
289 
290  if (!xmlSetProp((xmlNode *) node, (xmlChar *) name, (xmlChar *) value)) {
291  return -1;
292  }
293 
294  return 0;
295 }
296 
297 struct ast_xml_node *ast_xml_find_element(struct ast_xml_node *root_node, const char *name, const char *attrname, const char *attrvalue)
298 {
299  struct ast_xml_node *cur;
300  const char *attr;
301 
302  if (!root_node) {
303  return NULL;
304  }
305 
306  for (cur = root_node; cur; cur = ast_xml_node_get_next(cur)) {
307  /* Check if the name matchs */
308  if (strcmp(ast_xml_node_get_name(cur), name)) {
309  continue;
310  }
311  /* We need to check for a specific attribute name? */
312  if (!attrname || !attrvalue) {
313  return cur;
314  }
315  /* Get the attribute, we need to compare it. */
316  if ((attr = ast_xml_get_attribute(cur, attrname))) {
317  /* does attribute name/value matches? */
318  if (!strcmp(attr, attrvalue)) {
319  ast_xml_free_attr(attr);
320  return cur;
321  }
322  ast_xml_free_attr(attr);
323  }
324  }
325 
326  return NULL;
327 }
328 
329 struct ast_xml_doc *ast_xml_get_doc(struct ast_xml_node *node)
330 {
331  if (!node) {
332  return NULL;
333  }
334 
335  return (struct ast_xml_doc *) ((xmlNode *)node)->doc;
336 }
337 
338 struct ast_xml_ns *ast_xml_find_namespace(struct ast_xml_doc *doc, struct ast_xml_node *node, const char *ns_name) {
339  xmlNsPtr ns = xmlSearchNs((xmlDocPtr) doc, (xmlNodePtr) node, (xmlChar *) ns_name);
340  return (struct ast_xml_ns *) ns;
341 }
342 
343 const char *ast_xml_get_ns_prefix(struct ast_xml_ns *ns)
344 {
345  return (const char *) ((xmlNsPtr) ns)->prefix;
346 }
347 
348 const char *ast_xml_get_ns_href(struct ast_xml_ns *ns)
349 {
350  return (const char *) ((xmlNsPtr) ns)->href;
351 }
352 
353 const char *ast_xml_get_text(struct ast_xml_node *node)
354 {
355  if (!node) {
356  return NULL;
357  }
358 
359  return (const char *) xmlNodeGetContent((xmlNode *) node);
360 }
361 
362 void ast_xml_set_text(struct ast_xml_node *node, const char *content)
363 {
364  if (!node || !content) {
365  return;
366  }
367 
368  xmlNodeSetContent((xmlNode *) node, (const xmlChar *) content);
369 }
370 
371 void ast_xml_set_name(struct ast_xml_node *node, const char *name)
372 {
373  if (!node || !name) {
374  return;
375  }
376 
377  xmlNodeSetName((xmlNode *) node, (const xmlChar *) name);
378 }
379 
380 int ast_xml_doc_dump_file(FILE *output, struct ast_xml_doc *doc)
381 {
382  return xmlDocDump(output, (xmlDocPtr)doc);
383 }
384 
385 void ast_xml_doc_dump_memory(struct ast_xml_doc *doc, char **buffer, int *length)
386 {
387  xmlDocDumpFormatMemory((xmlDocPtr)doc, (xmlChar **)buffer, length, 1);
388 }
389 
390 const char *ast_xml_node_get_name(struct ast_xml_node *node)
391 {
392  return (const char *) ((xmlNode *) node)->name;
393 }
394 
395 struct ast_xml_node *ast_xml_node_get_children(struct ast_xml_node *node)
396 {
397  return (struct ast_xml_node *) ((xmlNode *) node)->children;
398 }
399 
400 struct ast_xml_node *ast_xml_node_get_next(struct ast_xml_node *node)
401 {
402  return (struct ast_xml_node *) ((xmlNode *) node)->next;
403 }
404 
405 struct ast_xml_node *ast_xml_node_get_prev(struct ast_xml_node *node)
406 {
407  return (struct ast_xml_node *) ((xmlNode *) node)->prev;
408 }
409 
410 struct ast_xml_node *ast_xml_node_get_parent(struct ast_xml_node *node)
411 {
412  return (struct ast_xml_node *) ((xmlNode *) node)->parent;
413 }
414 
415 struct ast_xml_node *ast_xml_xpath_get_first_result(struct ast_xml_xpath_results *results)
416 {
417  return (struct ast_xml_node *) ((xmlXPathObjectPtr) results)->nodesetval->nodeTab[0];
418 }
419 
420 struct ast_xml_node *ast_xml_xpath_get_result(struct ast_xml_xpath_results *results, int i)
421 {
422  return (struct ast_xml_node *) ((xmlXPathObjectPtr) results)->nodesetval->nodeTab[i];
423 }
424 
425 void ast_xml_xpath_results_free(struct ast_xml_xpath_results *results)
426 {
427  if (!results) {
428  return;
429  }
430  xmlXPathFreeObject((xmlXPathObjectPtr) results);
431 }
432 
433 int ast_xml_xpath_num_results(struct ast_xml_xpath_results *results)
434 {
435  if (!results) {
436  return 0;
437  }
438  return ((xmlXPathObjectPtr) results)->nodesetval->nodeNr;
439 }
440 
441 struct ast_xml_xpath_results *ast_xml_query(struct ast_xml_doc *doc, const char *xpath_str)
442 {
443  xmlXPathContextPtr context;
444  xmlXPathObjectPtr result;
445  if (!(context = xmlXPathNewContext((xmlDoc *) doc))) {
446  ast_log(LOG_ERROR, "Could not create XPath context!\n");
447  return NULL;
448  }
449  result = xmlXPathEvalExpression((xmlChar *) xpath_str, context);
450  xmlXPathFreeContext(context);
451  if (!result) {
452  ast_log(LOG_WARNING, "Error for query: %s\n", xpath_str);
453  return NULL;
454  }
455  if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
456  xmlXPathFreeObject(result);
457  ast_debug(5, "No results for query: %s\n", xpath_str);
458  return NULL;
459  }
460  return (struct ast_xml_xpath_results *) result;
461 }
462 
463 struct ast_xml_xpath_results *ast_xml_query_with_namespaces(struct ast_xml_doc *doc, const char *xpath_str,
464  struct ast_xml_namespace_def_vector *namespaces)
465 {
466  xmlXPathContextPtr context;
467  xmlXPathObjectPtr result;
468  int i;
469 
470  if (!(context = xmlXPathNewContext((xmlDoc *) doc))) {
471  ast_log(LOG_ERROR, "Could not create XPath context!\n");
472  return NULL;
473  }
474 
475  for (i = 0; i < AST_VECTOR_SIZE(namespaces); i++) {
476  struct ast_xml_namespace_def ns = AST_VECTOR_GET(namespaces, i);
477  if (xmlXPathRegisterNs(context, (xmlChar *)ns.prefix,
478  (xmlChar *)ns.href) != 0) {
479  xmlXPathFreeContext(context);
480  ast_log(LOG_ERROR, "Could not register namespace %s:%s\n",
481  ns.prefix, ns.href);
482  return NULL;
483  }
484  }
485 
486  result = xmlXPathEvalExpression((xmlChar *) xpath_str, context);
487  xmlXPathFreeContext(context);
488  if (!result) {
489  ast_log(LOG_WARNING, "Error for query: %s\n", xpath_str);
490  return NULL;
491  }
492  if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
493  xmlXPathFreeObject(result);
494  ast_debug(5, "No results for query: %s\n", xpath_str);
495  return NULL;
496  }
497  return (struct ast_xml_xpath_results *) result;
498 }
499 
500 #ifdef HAVE_LIBXSLT
501 struct ast_xslt_doc *ast_xslt_open(char *filename)
502 {
503  xsltStylesheet *xslt;
504  xmlDoc *xml;
505 
506  xml = xmlReadFile(filename, NULL, XML_PARSE_RECOVER | XML_PARSE_NOENT);
507  if (!xml) {
508  return NULL;
509  }
510 
511  if (process_xincludes(xml) < 0) {
512  xmlFreeDoc(xml);
513  return NULL;
514  }
515  xmlXPathOrderDocElems(xml);
516 
517  if (!(xslt = xsltParseStylesheetDoc(xml))) {
518  xmlFreeDoc(xml);
519  return NULL;
520  }
521 
522  return (struct ast_xslt_doc *) xslt;
523 }
524 
525 struct ast_xslt_doc *ast_xslt_read_memory(char *buffer, size_t size)
526 {
527  xsltStylesheet *xslt;
528  xmlDoc *doc;
529 
530  if (!buffer) {
531  return NULL;
532  }
533 
534  doc = xmlReadMemory(buffer, (int) size, NULL, NULL, XML_PARSE_RECOVER | XML_PARSE_NOENT);
535  if (!doc) {
536  return NULL;
537  }
538 
539  if (process_xincludes(doc) < 0) {
540  xmlFreeDoc(doc);
541  return NULL;
542  }
543 
544  if (!(xslt = xsltParseStylesheetDoc(doc))) {
545  xmlFreeDoc(doc);
546  return NULL;
547  }
548 
549  return (struct ast_xslt_doc *) xslt;
550 }
551 
552 void ast_xslt_close(struct ast_xslt_doc *axslt)
553 {
554  if (!axslt) {
555  return;
556  }
557 
558  xsltFreeStylesheet((xsltStylesheet *) axslt);
559 }
560 
561 struct ast_xml_doc *ast_xslt_apply(struct ast_xslt_doc *axslt, struct ast_xml_doc *axml, const char **params)
562 {
563  xsltStylesheet *xslt = (xsltStylesheet *)axslt;
564  xmlDoc *xml = (xmlDoc *)axml;
565  xmlDoc *res;
566  xsltTransformContextPtr ctxt;
567  xmlNs *ns;
568  int options = XSLT_PARSE_OPTIONS;
569 
570  /*
571  * Normally we could just call xsltApplyStylesheet() without creating
572  * our own transform context but passing parameters to it that have
573  * namespace prefixes isn't supported. Instead we have to create a
574  * transform context, iterate over the namespace declarations in the
575  * stylesheet (not the incoming xml document), add them to the
576  * transform context's xpath context, and call xsltApplyStylesheetUser.
577  *
578  * Since this is a bit involved and libxslt apparently doesn't completely
579  * clean up after itself in this situation, we'll only do that dance
580  * if there are parameters passed in. Otherwise we just call the simpler
581  * xsltApplyStylesheet.
582  *
583  */
584 
585  if (!params) {
586  res = xsltApplyStylesheet(xslt, xml, params);
587  return (struct ast_xml_doc *)res;
588  }
589 
590  ctxt = xsltNewTransformContext(xslt, xml);
591  xsltSetCtxtParseOptions(ctxt, options);
592 
593  for (ns = xslt->doc->children->nsDef; ns; ns = ns->next) {
594  if (xmlXPathRegisterNs(ctxt->xpathCtxt, ns->prefix, ns->href) != 0) {
595  xsltFreeTransformContext(ctxt);
596  return NULL;
597  }
598  }
599 
600  res = xsltApplyStylesheetUser(xslt, xml, params, NULL, NULL, ctxt);
601  xmlXPathFreeContext(ctxt->xpathCtxt);
602  ctxt->xpathCtxt = NULL;
603  xsltFreeTransformContext(ctxt);
604 
605  return (struct ast_xml_doc *)res;
606 }
607 
608 int ast_xslt_save_result_to_string(char **buffer, int *length, struct ast_xml_doc *result,
609  struct ast_xslt_doc *axslt)
610 {
611  return xsltSaveResultToString((xmlChar **)buffer, length, (xmlDoc *)result, (xsltStylesheet *)axslt);
612 }
613 
614 #endif /* defined(HAVE_LIBXSLT) */
615 #endif /* defined(HAVE_LIBXML2) */
Definition: test_heap.c:38
const char * ast_xml_get_text(struct ast_xml_node *node)
Get an element content string.
Definition: xml.c:353
Asterisk main include file. File version handling, generic pbx functions.
void ast_xml_free_text(const char *text)
Free a content element that was returned by ast_xml_get_text()
Definition: xml.c:260
struct ast_xml_doc * ast_xml_new(void)
Create a XML document.
Definition: xml.c:136
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:441
const char * ast_xml_get_ns_prefix(struct ast_xml_ns *ns)
Get the prefix of a namespace.
Definition: xml.c:343
void ast_xml_xpath_results_free(struct ast_xml_xpath_results *results)
Free the XPath results.
Definition: xml.c:425
void ast_xml_set_text(struct ast_xml_node *node, const char *content)
Set an element content string.
Definition: xml.c:362
int ast_xml_init(void)
Initialize the XML library implementation. This function is used to setup everything needed to start ...
Definition: xml.c:48
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:156
int ast_xml_xpath_num_results(struct ast_xml_xpath_results *results)
Return the number of results from an XPath query.
Definition: xml.c:433
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:184
const char * ast_xml_get_ns_href(struct ast_xml_ns *ns)
Get the href of a namespace.
Definition: xml.c:348
void ast_xml_close(struct ast_xml_doc *doc)
Close an already open document and free the used structure.
Definition: xml.c:211
void ast_xml_free_attr(const char *attribute)
Free an attribute returned by ast_xml_get_attribute()
Definition: xml.c:253
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:463
Utility functions.
int ast_xml_doc_dump_file(FILE *output, struct ast_xml_doc *doc)
Dump the specified document to a file.
Definition: xml.c:380
const char * ast_xml_get_attribute(struct ast_xml_node *node, const char *attrname)
Get a node attribute by name.
Definition: xml.c:267
const char * ast_xml_node_get_name(struct ast_xml_node *node)
Get the name of a node.
Definition: xml.c:390
void ast_xslt_close(struct ast_xslt_doc *axslt)
Close a stylesheet document and free its resources.
Definition: xml.c:552
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:168
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:420
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:400
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_xml_node * ast_xml_node_get_children(struct ast_xml_node *node)
Get the node's children.
Definition: xml.c:395
Asterisk XML abstraction layer.
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:221
struct ast_xml_doc * ast_xml_get_doc(struct ast_xml_node *node)
Get the document based on a node.
Definition: xml.c:329
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:405
void ast_xml_doc_dump_memory(struct ast_xml_doc *doc, char **buffer, int *length)
Dump the specified document to a buffer.
Definition: xml.c:385
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:415
Support for logging to various files, console and syslog Configuration in file logger.conf.
struct ast_xml_node * ast_xml_new_node(const char *name)
Create a XML node.
Definition: xml.c:144
Namespace definition.
Definition: xml.h:325
struct ast_xml_doc * ast_xml_read_memory(char *buffer, size_t size)
Open an XML document that resides in memory.
Definition: xml.c:192
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:284
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680
struct ast_xml_node * ast_xml_node_get_parent(struct ast_xml_node *node)
Get the parent of a specified node.
Definition: xml.c:410
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:176
void ast_xml_set_name(struct ast_xml_node *node, const char *name)
Set or reset an element's name.
Definition: xml.c:371
struct ast_xml_node * ast_xml_get_root(struct ast_xml_doc *doc)
Get the document root node.
Definition: xml.c:230
struct ast_xml_doc * ast_xslt_apply(struct ast_xslt_doc *axslt, struct ast_xml_doc *axml, const char **params)
Apply an XSLT stylesheet to an XML document.
Definition: xml.c:561
struct ast_xslt_doc * ast_xslt_open(char *filename)
Open an XSLT document.
Definition: xml.c:501
struct ast_xml_doc * ast_xml_open(char *filename)
Open an XML document.
Definition: xml.c:94
int ast_xslt_save_result_to_string(char **buffer, int *length, struct ast_xml_doc *result, struct ast_xslt_doc *axslt)
Save the results of applying a stylesheet to a string.
Definition: xml.c:608
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
void ast_xml_free_node(struct ast_xml_node *node)
Free node.
Definition: xml.c:243
struct ast_xslt_doc * ast_xslt_read_memory(char *buffer, size_t size)
Open an XSLT document that resides in memory.
Definition: xml.c:525
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:297
int ast_xml_finish(void)
Cleanup library allocated global data.
Definition: xml.c:57