6 This section gives details about the functions in libxo, how to call
7 them, and the actions they perform.
15 libxo uses "handles" to control its rendering functionality. The
16 handle contains state and buffered data, as well as callback functions
19 Handles give an abstraction for libxo that encapsulates the state of a
20 stream of output. Handles have the data type "`xo_handle_t`" and are
23 The library has a default handle that is automatically initialized.
24 By default, this handle will send text style output (`XO_STYLE_TEXT`) to
25 standard output. The xo_set_style and xo_set_flags functions can be
26 used to change this behavior.
28 For the typical command that is generating output on standard output,
29 there is no need to create an explicit handle, but they are available
30 when needed, e.g., for daemons that generate multiple streams of
33 Many libxo functions take a handle as their first parameter; most that
34 do not use the default handle. Any function taking a handle can be
35 passed NULL to access the default handle. For the convenience of
36 callers, the libxo library includes handle-less functions that
37 implicitly use the default handle.
39 For example, the following are equivalent::
42 xo_emit_h(NULL, "test");
44 Handles are created using `xo_create` and destroy using
52 .. c:function:: xo_handle_t *xo_create (xo_style_t style, xo_xof_flags_t flags)
54 The `xo_create` function allocates a new handle which can be passed
55 to further libxo function calls. The `xo_handle_t` structure is
58 :param xo_style_t style: Output style (XO_STYLE\_*)
59 :param xo_xof_flags_t flags: Flags for this handle (XOF\_*)
60 :return: New libxo handle
61 :rtype: xo_handle_t \*
66 xo_handle_t *xop = xo_create(XO_STYLE_JSON, XOF_WARN | XOF_PRETTY);
68 xo_emit_h(xop, "testing\n");
70 See also :ref:`output-styles` and :ref:`flags`.
72 .. index:: xo_create_to_file
73 .. index:: XOF_CLOSE_FP
79 xo_handle_t *xo_create_to_file (FILE *fp, unsigned style, unsigned flags)
81 The `xo_create_to_file` function is aconvenience function is
82 provided for situations when output should be written to a different
83 file, rather than the default of standard output.
85 The `XOF_CLOSE_FP` flag can be set on the returned handle to trigger a
86 call to fclose() for the FILE pointer when the handle is destroyed,
87 avoiding the need for the caller to perform this task.
89 :param fp: FILE to use as base for this handle
91 :param xo_style_t style: Output style (XO_STYLE\_*)
92 :param xo_xof_flags_t flags: Flags for this handle (XOF\_*)
93 :return: New libxo handle
94 :rtype: xo_handle_t \*
96 .. index:: xo_set_writer
97 .. index:: xo_write_func_t
98 .. index:: xo_close_func_t
99 .. index:: xo_flush_func_t
105 void xo_set_writer (xo_handle_t *xop, void *opaque, \
106 xo_write_func_t write_func, xo_close_func_t close_func, \
107 xo_flush_func_t flush_func)
109 The `xo_set_writer` function allows custom functions which can
110 tailor how libxo writes data. The `opaque` argument is recorded and
111 passed back to the functions, allowing the function to acquire
112 context information. The *write_func* function writes data to the
113 output stream. The *close_func* function can release this opaque
114 data and any other resources as needed. The *flush_func* function
115 is called to flush buffered data associated with the opaque object.
117 :param xop: Handle to modify (or NULL for default handle)
118 :type xop: xo_handle_t *
119 :param opaque: Pointer to opaque data passed to the given functions
121 :param xo_write_func_t write_func: New write function
122 :param xo_close_func_t close_func: New close function
123 :param xo_flush_func_t flush_func: New flush function
126 .. index:: xo_get_style
131 .. c:function:: xo_style_t xo_get_style(xo_handle_t *xop)
133 Use the `xo_get_style` function to find the current output style for
134 a given handle. To use the default handle, pass a `NULL` handle.
136 :param xop: Handle to interrogate (or NULL for default handle)
137 :type xop: xo_handle_t *
138 :returns: Output style (XO_STYLE\_*)
144 style = xo_get_style(NULL);
146 .. index:: XO_STYLE_TEXT
147 .. index:: XO_STYLE_XML
148 .. index:: XO_STYLE_JSON
149 .. index:: XO_STYLE_HTML
153 Output Styles (XO_STYLE\_\*)
154 ++++++++++++++++++++++++++++
156 The libxo functions accept a set of output styles:
158 =============== =========================
160 =============== =========================
161 XO_STYLE_TEXT Traditional text output
162 XO_STYLE_XML XML encoded data
163 XO_STYLE_JSON JSON encoded data
164 XO_STYLE_HTML HTML encoded data
165 =============== =========================
167 The "XML", "JSON", and "HTML" output styles all use the UTF-8
168 character encoding. "TEXT" using locale-based encoding.
170 .. index:: xo_set_style
175 .. c:function:: void xo_set_style(xo_handle_t *xop, xo_style_t style)
177 The `xo_set_style` function is used to change the output style
178 setting for a handle. To use the default handle, pass a `NULL`
181 :param xop: Handle to modify
182 :type xop: xo_handle_t *
183 :param xo_style_t style: Output style (XO_STYLE\_*)
189 xo_set_style(NULL, XO_STYLE_XML);
191 .. index:: xo_set_style_name
196 .. c:function:: int xo_set_style_name (xo_handle_t *xop, const char *style)
198 The `xo_set_style_name` function can be used to set the style based
199 on a name encoded as a string: The name can be any of the supported
200 styles: "text", "xml", "json", or "html".
202 :param xop: Handle for modify (or NULL for default handle)
203 :type xop: xo_handle_t \*
204 :param style: Text name of the style
205 :type style: const char \*
206 :returns: zero for success, non-zero for error
212 xo_set_style_name(NULL, "html");
214 .. index:: xo_set_flags
219 .. c:function:: void xo_set_flags(xo_handle_t *xop, xo_xof_flags_t flags)
221 :param xop: Handle for modify (or NULL for default handle)
222 :type xop: xo_handle_t \*
223 :param xo_xof_flags_t flags: Flags to add for the handle
226 Use the `xo_set_flags` function to turn on flags for a given libxo
227 handle. To use the default handle, pass a `NULL` handle.
232 xo_set_flags(NULL, XOF_PRETTY | XOF_WARN);
234 .. index:: Flags; XOF_*
235 .. index:: XOF_CLOSE_FP
237 .. index:: XOF_COLOR_ALLOWED
241 .. index:: XOF_NO_ENV
242 .. index:: XOF_NO_HUMANIZE
243 .. index:: XOF_PRETTY
244 .. index:: XOF_UNDERSCORES
247 .. index:: XOF_WARN_XML
249 .. index:: XOF_COLUMNS
257 The set of valid flags include:
259 =================== =========================================
261 =================== =========================================
262 XOF_CLOSE_FP Close file pointer on `xo_destroy`
263 XOF_COLOR Enable color and effects in output
264 XOF_COLOR_ALLOWED Allow color/effect for terminal output
265 XOF_DTRT Enable "do the right thing" mode
266 XOF_INFO Display info data attributes (HTML)
267 XOF_KEYS Emit the key attribute (XML)
268 XOF_NO_ENV Do not use the :ref:`libxo-options` env var
269 XOF_NO_HUMANIZE Display humanization (TEXT, HTML)
270 XOF_PRETTY Make "pretty printed" output
271 XOF_UNDERSCORES Replaces hyphens with underscores
272 XOF_UNITS Display units (XML, HMTL)
273 XOF_WARN Generate warnings for broken calls
274 XOF_WARN_XML Generate warnings in XML on stdout
275 XOF_XPATH Emit XPath expressions (HTML)
276 XOF_COLUMNS Force xo_emit to return columns used
277 XOF_FLUSH Flush output after each `xo_emit` call
278 =================== =========================================
280 The `XOF_CLOSE_FP` flag will trigger the call of the *close_func*
281 (provided via `xo_set_writer`) when the handle is destroyed.
283 The `XOF_COLOR` flag enables color and effects in output regardless
284 of output device, while the `XOF_COLOR_ALLOWED` flag allows color
285 and effects only if the output device is a terminal.
287 The `XOF_PRETTY` flag requests "pretty printing", which will trigger
288 the addition of indentation and newlines to enhance the readability of
289 XML, JSON, and HTML output. Text output is not affected.
291 The `XOF_WARN` flag requests that warnings will trigger diagnostic
292 output (on standard error) when the library notices errors during
293 operations, or with arguments to functions. Without warnings enabled,
294 such conditions are ignored.
296 Warnings allow developers to debug their interaction with libxo.
297 The function `xo_failure` can used as a breakpoint for a debugger,
298 regardless of whether warnings are enabled.
300 If the style is `XO_STYLE_HTML`, the following additional flags can be
303 =============== =========================================
305 =============== =========================================
306 XOF_XPATH Emit "data-xpath" attributes
307 XOF_INFO Emit additional info fields
308 =============== =========================================
310 The `XOF_XPATH` flag enables the emission of XPath expressions detailing
311 the hierarchy of XML elements used to encode the data field, if the
312 XPATH style of output were requested.
314 The `XOF_INFO` flag encodes additional informational fields for HTML
315 output. See :ref:`field-information` for details.
317 If the style is `XO_STYLE_XML`, the following additional flags can be
320 =============== =========================================
322 =============== =========================================
323 XOF_KEYS Flag "key" fields for XML
324 =============== =========================================
326 The `XOF_KEYS` flag adds "key" attribute to the XML encoding for
327 field definitions that use the "k" modifier. The key attribute has
330 xo_emit("{k:name}", item);
333 <name key="key">truck</name>
335 .. index:: xo_clear_flags
340 .. c:function:: void xo_clear_flags (xo_handle_t *xop, xo_xof_flags_t flags)
342 :param xop: Handle for modify (or NULL for default handle)
343 :type xop: xo_handle_t \*
344 :param xo_xof_flags_t flags: Flags to clear for the handle
347 Use the `xo_clear_flags` function to turn off the given flags in a
348 specific handle. To use the default handle, pass a `NULL` handle.
350 .. index:: xo_set_options
355 .. c:function:: int xo_set_options (xo_handle_t *xop, const char *input)
357 :param xop: Handle for modify (or NULL for default handle)
358 :type xop: xo_handle_t \*
359 :param input: string containing options to set
360 :type input: const char *
361 :returns: zero for success, non-zero for error
364 The `xo_set_options` function accepts a comma-separated list of
365 output styles and modifier flags and enables them for a specific
366 handle. The options are identical to those listed in
367 :ref:`options`. To use the default handle, pass a `NULL` handle.
369 .. index:: xo_destroy
374 .. c:function:: void xo_destroy(xo_handle_t *xop)
376 :param xop: Handle for modify (or NULL for default handle)
377 :type xop: xo_handle_t \*
380 The `xo_destroy` function releases a handle and any resources it is
381 using. Calling `xo_destroy` with a `NULL` handle will release any
382 resources associated with the default handle.
386 Emitting Content (xo_emit)
387 --------------------------
389 The functions in this section are used to emit output.
391 The "fmt" argument is a string containing field descriptors as
392 specified in :ref:`format-strings`. The use of a handle is optional and
393 `NULL` can be passed to access the internal "default" handle. See
396 The remaining arguments to `xo_emit` and `xo_emit_h` are a set of
397 arguments corresponding to the fields in the format string. Care must
398 be taken to ensure the argument types match the fields in the format
399 string, since an inappropriate cast can ruin your day. The vap
400 argument to `xo_emit_hv` points to a variable argument list that can
401 be used to retrieve arguments via `va_arg`.
403 .. c:function:: xo_ssize_t xo_emit (const char *fmt, ...)
405 :param fmt: The format string, followed by zero or more arguments
406 :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
409 .. c:function:: xo_ssize_t xo_emit_h (xo_handle_t *xop, const char *fmt, ...)
411 :param xop: Handle for modify (or NULL for default handle)
412 :type xop: xo_handle_t \*
413 :param fmt: The format string, followed by zero or more arguments
414 :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
417 .. c:function:: xo_ssize_t xo_emit_hv (xo_handle_t *xop, const char *fmt, va_list vap)
419 :param xop: Handle for modify (or NULL for default handle)
420 :type xop: xo_handle_t \*
421 :param fmt: The format string
422 :param va_list vap: A set of variadic arguments
423 :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
426 .. index:: xo_emit_field
428 Single Field Emitting Functions (xo_emit_field)
429 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
431 The functions in this section can also make output, but only make a
432 single field at a time. These functions are intended to avoid the
433 scenario where one would otherwise need to compose a format
434 descriptors using `snprintf`. The individual parts of the format
435 descriptor are passed in distinctly.
437 .. c:function:: xo_ssize_t xo_emit_field (const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...)
439 :param rolmod: A comma-separated list of field roles and field modifiers
440 :type rolmod: const char *
441 :param contents: The "contents" portion of the field description string
442 :type contents: const char *
443 :param fmt: Content format string
444 :type fmt: const char *
445 :param efmt: Encoding format string, followed by additional arguments
446 :type efmt: const char *
447 :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
453 xo_emit_field("T", "Host name is ", NULL, NULL);
454 xo_emit_field("V", "host-name", NULL, NULL, host-name);
456 .. c:function:: xo_ssize_t xo_emit_field_h (xo_handle_t *xop, const char *rolmod, const char *contents, const char *fmt, const char *efmt, ...)
458 :param xop: Handle for modify (or NULL for default handle)
459 :type xop: xo_handle_t \*
460 :param rolmod: A comma-separated list of field roles and field modifiers
461 :type rolmod: const char *
462 :param contents: The "contents" portion of the field description string
463 :type contents: const char *
464 :param fmt: Content format string
465 :type fmt: const char *
466 :param efmt: Encoding format string, followed by additional arguments
467 :type efmt: const char *
468 :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
471 .. c:function:: xo_ssize_t xo_emit_field_hv (xo_handle_t *xop, const char *rolmod, const char *contents, const char *fmt, const char *efmt, va_list vap)
473 :param xop: Handle for modify (or NULL for default handle)
474 :type xop: xo_handle_t \*
475 :param rolmod: A comma-separated list of field roles and field modifiers
476 :type rolmod: const char *
477 :param contents: The "contents" portion of the field description string
478 :type contents: const char *
479 :param fmt: Content format string
480 :type fmt: const char *
481 :param efmt: Encoding format string
482 :type efmt: const char *
483 :param va_list vap: A set of variadic arguments
484 :returns: If XOF_COLUMNS is set, the number of columns used; otherwise the number of bytes emitted
493 The functions in this section emit an XML attribute with the given name
494 and value. This only affects the XML output style.
496 The `name` parameter give the name of the attribute to be encoded. The
497 `fmt` parameter gives a printf-style format string used to format the
498 value of the attribute using any remaining arguments, or the vap
499 parameter passed to `xo_attr_hv`.
501 All attributes recorded via `xo_attr` are placed on the next
502 container, instance, leaf, or leaf list that is emitted.
504 Since attributes are only emitted in XML, their use should be limited
505 to meta-data and additional or redundant representations of data
506 already emitted in other form.
508 .. c:function:: xo_ssize_t xo_attr (const char *name, const char *fmt, ...)
510 :param name: Attribute name
511 :type name: const char *
512 :param fmt: Attribute value, as variadic arguments
513 :type fmt: const char *
514 :returns: -1 for error, or the number of bytes in the formatted attribute value
520 xo_attr("seconds", "%ld", (unsigned long) login_time);
521 struct tm *tmp = localtime(login_time);
522 strftime(buf, sizeof(buf), "%R", tmp);
523 xo_emit("Logged in at {:login-time}\n", buf);
525 <login-time seconds="1408336270">00:14</login-time>
528 .. c:function:: xo_ssize_t xo_attr_h (xo_handle_t *xop, const char *name, const char *fmt, ...)
530 :param xop: Handle for modify (or NULL for default handle)
531 :type xop: xo_handle_t \*
533 The `xo_attr_h` function follows the conventions of `xo_attr` but
534 adds an explicit libxo handle.
536 .. c:function:: xo_ssize_t xo_attr_hv (xo_handle_t *xop, const char *name, const char *fmt, va_list vap)
538 The `xo_attr_h` function follows the conventions of `xo_attr_h`
539 but replaced the variadic list with a variadic pointer.
543 Flushing Output (xo_flush)
544 ~~~~~~~~~~~~~~~~~~~~~~~~~~
546 .. c:function:: xo_ssize_t xo_flush (void)
548 :returns: -1 for error, or the number of bytes generated
551 libxo buffers data, both for performance and consistency, but also
552 to allow for the proper function of various advanced features. At
553 various times, the caller may wish to flush any data buffered within
554 the library. The `xo_flush` call is used for this.
556 Calling `xo_flush` also triggers the flush function associated with
557 the handle. For the default handle, this is equivalent to
560 .. c:function:: xo_ssize_t xo_flush_h (xo_handle_t *xop)
562 :param xop: Handle for flush (or NULL for default handle)
563 :type xop: xo_handle_t \*
564 :returns: -1 for error, or the number of bytes generated
567 The `xo_flush_h` function follows the conventions of `xo_flush`,
568 but adds an explicit libxo handle.
571 .. index:: xo_finish_atexit
574 Finishing Output (xo_finish)
575 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
577 When the program is ready to exit or close a handle, a call to
578 `xo_finish` or `xo_finish_h` is required. This flushes any buffered
579 data, closes open libxo constructs, and completes any pending
582 Calling this function is vital to the proper operation of libxo,
583 especially for the non-TEXT output styles.
585 .. c:function:: xo_ssize_t xo_finish (void)
587 :returns: -1 on error, or the number of bytes flushed
590 .. c:function:: xo_ssize_t xo_finish_h (xo_handle_t *xop)
592 :param xop: Handle for finish (or NULL for default handle)
593 :type xop: xo_handle_t \*
594 :returns: -1 on error, or the number of bytes flushed
597 .. c:function:: void xo_finish_atexit (void)
599 The `xo_finish_atexit` function is suitable for use with
600 :manpage:`atexit(3)` to ensure that `xo_finish` is called
601 on the default handle when the application exits.
604 .. index:: xo_open_container
605 .. index:: xo_close_container
610 libxo represents two types of hierarchy: containers and lists. A
611 container appears once under a given parent where a list consists of
612 instances that can appear multiple times. A container is used to hold
613 related fields and to give the data organization and scope.
617 .. admonition:: YANG Terminology
619 libxo uses terminology from YANG (:RFC:`7950`), the data modeling
620 language for NETCONF: container, list, leaf, and leaf-list.
622 For XML and JSON, individual fields appear inside hierarchies which
623 provide context and meaning to the fields. Unfortunately, these
624 encoding have a basic disconnect between how lists is similar objects
627 XML encodes lists as set of sequential elements::
633 JSON encodes lists using a single name and square brackets::
635 "user": [ "phil", "pallavi", "sjg" ]
637 This means libxo needs three distinct indications of hierarchy: one
638 for containers of hierarchy appear only once for any specific parent,
639 one for lists, and one for each item in a list.
641 .. index:: Containers
646 A "*container*" is an element of a hierarchy that appears only once
647 under any specific parent. The container has no value, but serves to
648 contain and organize other nodes.
650 To open a container, call xo_open_container() or
651 xo_open_container_h(). The former uses the default handle and the
652 latter accepts a specific handle. To close a level, use the
653 xo_close_container() or xo_close_container_h() functions.
655 Each open call must have a matching close call. If the XOF_WARN flag
656 is set and the name given does not match the name of the currently open
657 container, a warning will be generated.
659 .. c:function:: xo_ssize_t xo_open_container (const char *name)
661 :param name: Name of the container
662 :type name: const char *
663 :returns: -1 on error, or the number of bytes generated
666 The `name` parameter gives the name of the container, encoded in
667 UTF-8. Since ASCII is a proper subset of UTF-8, traditional C
668 strings can be used directly.
670 .. c:function:: xo_ssize_t xo_open_container_h (xo_handle_t *xop, const char *name)
672 :param xop: Handle to use (or NULL for default handle)
673 :type xop: xo_handle_t *
675 The `xo_open_container_h` function adds a `handle` parameter.
677 .. c:function:: xo_ssize_t xo_close_container (const char *name)
679 :param name: Name of the container
680 :type name: const char *
681 :returns: -1 on error, or the number of bytes generated
684 .. c:function:: xo_ssize_t xo_close_container_h (xo_handle_t *xop, const char *name)
686 :param xop: Handle to use (or NULL for default handle)
687 :type xop: xo_handle_t *
689 The `xo_close_container_h` function adds a `handle` parameter.
691 Use the :index:`XOF_WARN` flag to generate a warning if the name given
692 on the close does not match the current open container.
694 For TEXT and HTML output, containers are not rendered into output
695 text, though for HTML they are used to record an XPath value when the
696 :index:`XOF_XPATH` flag is set.
701 xo_open_container("top");
702 xo_open_container("system");
703 xo_emit("{:host-name/%s%s%s}", hostname,
704 domainname ? "." : "", domainname ?: "");
705 xo_close_container("system");
706 xo_close_container("top");
712 <host-name>my-host.example.org</host-name>
718 "host-name": "my-host.example.org"
723 data-tag="host-name">my-host.example.org</div>
725 .. index:: xo_open_instance
726 .. index:: xo_close_instance
727 .. index:: xo_open_list
728 .. index:: xo_close_list
733 A "*list*" is set of one or more instances that appear under the same
734 parent. The instances contain details about a specific object. One
735 can think of instances as objects or records. A call is needed to
736 open and close the list, while a distinct call is needed to open and
737 close each instance of the list.
739 The name given to all calls must be identical, and it is strongly
740 suggested that the name be singular, not plural, as a matter of
741 style and usage expectations::
744 xo_open_list("item");
746 for (ip = list; ip->i_title; ip++) {
747 xo_open_instance("item");
748 xo_emit("{L:Item} '{:name/%s}':\n", ip->i_title);
749 xo_close_instance("item");
752 xo_close_list("item");
754 Getting the list and instance calls correct is critical to the proper
755 generation of XML and JSON data.
760 .. c:function:: xo_ssize_t xo_open_list (const char *name)
762 :param name: Name of the list
763 :type name: const char *
764 :returns: -1 on error, or the number of bytes generated
767 The `xo_open_list` function open a list of instances.
769 .. c:function:: xo_ssize_t xo_open_list_h (xo_handle_t *xop, const char *name)
771 :param xop: Handle to use (or NULL for default handle)
772 :type xop: xo_handle_t *
777 .. c:function:: xo_ssize_t xo_close_list (const char *name)
779 :param name: Name of the list
780 :type name: const char *
781 :returns: -1 on error, or the number of bytes generated
784 The `xo_close_list` function closes a list of instances.
786 .. c:function:: xo_ssize_t xo_close_list_h (xo_handle_t *xop, const char *name)
788 :param xop: Handle to use (or NULL for default handle)
789 :type xop: xo_handle_t *
791 The `xo_close_container_h` function adds a `handle` parameter.
796 .. c:function:: xo_ssize_t xo_open_instance (const char *name)
798 :param name: Name of the instance (same as the list name)
799 :type name: const char *
800 :returns: -1 on error, or the number of bytes generated
803 The `xo_open_instance` function open a single instance.
805 .. c:function:: xo_ssize_t xo_open_instance_h (xo_handle_t *xop, const char *name)
807 :param xop: Handle to use (or NULL for default handle)
808 :type xop: xo_handle_t *
810 The `xo_open_instance_h` function adds a `handle` parameter.
815 .. c:function:: xo_ssize_t xo_close_instance (const char *name)
817 :param name: Name of the instance
818 :type name: const char *
819 :returns: -1 on error, or the number of bytes generated
822 The `xo_close_instance` function closes an open instance.
824 .. c:function:: xo_ssize_t xo_close_instance_h (xo_handle_t *xop, const char *name)
826 :param xop: Handle to use (or NULL for default handle)
827 :type xop: xo_handle_t *
829 The `xo_close_instance_h` function adds a `handle` parameter.
834 xo_open_list("user");
835 for (i = 0; i < num_users; i++) {
836 xo_open_instance("user");
837 xo_emit("{k:name}:{:uid/%u}:{:gid/%u}:{:home}\n",
838 pw[i].pw_name, pw[i].pw_uid,
839 pw[i].pw_gid, pw[i].pw_dir);
840 xo_close_instance("user");
842 xo_close_list("user");
844 phil:1001:1001:/home/phil
845 pallavi:1002:1002:/home/pallavi
851 <home>/home/phil</home>
857 <home>/home/pallavi</home>
865 "home": "/home/phil",
871 "home": "/home/pallavi",
878 Markers are used to protect and restore the state of open hierarchy
879 constructs (containers, lists, or instances). While a marker is open,
880 no other open constructs can be closed. When a marker is closed, all
881 constructs open since the marker was opened will be closed.
883 Markers use names which are not user-visible, allowing the caller to
884 choose appropriate internal names.
886 In this example, the code whiffles through a list of fish, calling a
887 function to emit details about each fish. The marker "fish-guts" is
888 used to ensure that any constructs opened by the function are closed
892 for (i = 0; fish[i]; i++) {
893 xo_open_instance("fish");
894 xo_open_marker("fish-guts");
895 dump_fish_details(i);
896 xo_close_marker("fish-guts");
899 .. c:function:: xo_ssize_t xo_open_marker(const char *name)
901 :param name: Name of the instance
902 :type name: const char *
903 :returns: -1 on error, or the number of bytes generated
906 The `xo_open_marker` function records the current state of open tags
907 in order for `xo_close_marker` to close them at some later point.
909 .. c:function:: xo_ssize_t xo_open_marker_h(const char *name)
911 :param xop: Handle to use (or NULL for default handle)
912 :type xop: xo_handle_t *
914 The `xo_open_marker_h` function adds a `handle` parameter.
916 .. c:function:: xo_ssize_t xo_close_marker(const char *name)
918 :param name: Name of the instance
919 :type name: const char *
920 :returns: -1 on error, or the number of bytes generated
923 The `xo_close_marker` function closes any open containers, lists, or
924 instances as needed to return to the state recorded when
925 `xo_open_marker` was called with the matching name.
927 .. c:function:: xo_ssize_t xo_close_marker(const char *name)
929 :param xop: Handle to use (or NULL for default handle)
930 :type xop: xo_handle_t *
932 The `xo_close_marker_h` function adds a `handle` parameter.
937 Some users may find tracking the names of open containers, lists, and
938 instances inconvenient. libxo offers a "Do The Right Thing" mode, where
939 libxo will track the names of open containers, lists, and instances so
940 the close function can be called without a name. To enable DTRT mode,
941 turn on the XOF_DTRT flag prior to making any other libxo output::
943 xo_set_flags(NULL, XOF_DTRT);
947 Each open and close function has a version with the suffix "_d", which
948 will close the open container, list, or instance::
950 xo_open_container_d("top");
952 xo_close_container_d();
954 This also works for lists and instances::
956 xo_open_list_d("item");
958 xo_open_instance_d("item");
960 xo_close_instance_d();
966 Note that the XOF_WARN flag will also cause libxo to track open
967 containers, lists, and instances. A warning is generated when the
968 name given to the close function and the name recorded do not match.
973 .. index:: xo_parse_args
976 Parsing Command-line Arguments (xo_parse_args)
977 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
979 .. c:function:: int xo_parse_args (int argc, char **argv)
981 :param int argc: Number of arguments
982 :param argv: Array of argument strings
983 :return: -1 on error, or the number of remaining arguments
986 The `xo_parse_args` function is used to process a program's
987 arguments. libxo-specific options are processed and removed from
988 the argument list so the calling application does not need to
989 process them. If successful, a new value for argc is returned. On
990 failure, a message is emitted and -1 is returned::
992 argc = xo_parse_args(argc, argv);
996 Following the call to xo_parse_args, the application can process the
997 remaining arguments in a normal manner. See :ref:`options` for a
998 description of valid arguments.
1000 .. index:: xo_set_program
1005 .. c:function:: void xo_set_program (const char *name)
1007 :param name: Name to use as the program name
1008 :type name: const char *
1011 The `xo_set_program` function sets the name of the program as
1012 reported by functions like `xo_failure`, `xo_warn`, `xo_err`, etc.
1013 The program name is initialized by `xo_parse_args`, but subsequent
1014 calls to `xo_set_program` can override this value::
1017 xo_set_program(argv[0]);
1019 Note that the value is not copied, so the memory passed to
1020 `xo_set_program` (and `xo_parse_args`) must be maintained by the
1023 .. index:: xo_set_version
1028 .. c:function:: void xo_set_version (const char *version)
1030 :param name: Value to use as the version string
1031 :type name: const char *
1034 The `xo_set_version` function records a version number to be emitted
1035 as part of the data for encoding styles (XML and JSON). This
1036 version number is suitable for tracking changes in the content,
1037 allowing a user of the data to discern which version of the data
1040 .. c:function:: void xo_set_version_h (xo_handle_t *xop, const char *version)
1042 :param xop: Handle to use (or NULL for default handle)
1043 :type xop: xo_handle_t *
1045 The `xo_set_version` function adds a `handle` parameter.
1049 .. index:: xo_info_t
1051 .. _field-information:
1053 Field Information (xo_info_t)
1054 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1056 HTML data can include additional information in attributes that
1057 begin with "data-". To enable this, three things must occur:
1059 First the application must build an array of xo_info_t structures,
1060 one per tag. The array must be sorted by name, since libxo uses a
1061 binary search to find the entry that matches names from format
1064 Second, the application must inform libxo about this information using
1065 the `xo_set_info` call::
1067 typedef struct xo_info_s {
1068 const char *xi_name; /* Name of the element */
1069 const char *xi_type; /* Type of field */
1070 const char *xi_help; /* Description of field */
1073 void xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count);
1075 Like other libxo calls, passing `NULL` for the handle tells libxo to
1076 use the default handle.
1078 If the count is -1, libxo will count the elements of infop, but there
1079 must be an empty element at the end. More typically, the number is
1080 known to the application::
1082 xo_info_t info[] = {
1083 { "in-stock", "number", "Number of items in stock" },
1084 { "name", "string", "Name of the item" },
1085 { "on-order", "number", "Number of items on order" },
1086 { "sku", "string", "Stock Keeping Unit" },
1087 { "sold", "number", "Number of items sold" },
1089 int info_count = (sizeof(info) / sizeof(info[0]));
1091 xo_set_info(NULL, info, info_count);
1093 Third, the emission of info must be triggered with the `XOF_INFO` flag
1094 using either the `xo_set_flags` function or the "`--libxo=info`"
1095 command line argument.
1097 The type and help values, if present, are emitted as the "data-type"
1098 and "data-help" attributes::
1100 <div class="data" data-tag="sku" data-type="string"
1101 data-help="Stock Keeping Unit">GRO-000-533</div>
1103 .. c:function:: void xo_set_info (xo_handle_t *xop, xo_info_t *infop, int count)
1105 :param xop: Handle to use (or NULL for default handle)
1106 :type xop: xo_handle_t *
1107 :param infop: Array of information structures
1108 :type infop: xo_info_t *
1111 .. index:: xo_set_allocator
1112 .. index:: xo_realloc_func_t
1113 .. index:: xo_free_func_t
1118 The `xo_set_allocator` function allows libxo to be used in
1119 environments where the standard :manpage:`realloc(3)` and
1120 :manpage:`free(3)` functions are not appropriate.
1122 .. c:function:: void xo_set_allocator (xo_realloc_func_t realloc_func, xo_free_func_t free_func)
1124 :param xo_realloc_func_t realloc_func: Allocation function
1125 :param xo_free_func_t free_func: Free function
1127 *realloc_func* should expect the same arguments as
1128 :manpage:`realloc(3)` and return a pointer to memory following the
1129 same convention. *free_func* will receive the same argument as
1130 :manpage:`free(3)` and should release it, as appropriate for the
1133 By default, the standard :manpage:`realloc(3)` and :manpage:`free(3)`
1143 The environment variable "LIBXO_OPTIONS" can be set to a subset of
1144 libxo options, including:
1158 For example, warnings can be enabled by::
1160 % env LIBXO_OPTIONS=warn my-app
1162 Since environment variables are inherited, child processes will have
1163 the same options, which may be undesirable, making the use of the
1164 "`--libxo`" command-line option preferable in most situations.
1169 .. index:: xo_message
1171 Errors, Warnings, and Messages
1172 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1174 Many programs make use of the standard library functions
1175 :manpage:`err(3)` and :manpage:`warn(3)` to generate errors and
1176 warnings for the user. libxo wants to pass that information via the
1177 current output style, and provides compatible functions to allow
1180 void xo_warn (const char *fmt, ...);
1181 void xo_warnx (const char *fmt, ...);
1182 void xo_warn_c (int code, const char *fmt, ...);
1183 void xo_warn_hc (xo_handle_t *xop, int code,
1184 const char *fmt, ...);
1185 void xo_err (int eval, const char *fmt, ...);
1186 void xo_errc (int eval, int code, const char *fmt, ...);
1187 void xo_errx (int eval, const char *fmt, ...);
1191 void xo_message (const char *fmt, ...);
1192 void xo_message_c (int code, const char *fmt, ...);
1193 void xo_message_hc (xo_handle_t *xop, int code,
1194 const char *fmt, ...);
1195 void xo_message_hcv (xo_handle_t *xop, int code,
1196 const char *fmt, va_list vap);
1198 These functions display the program name, a colon, a formatted message
1199 based on the arguments, and then optionally a colon and an error
1200 message associated with either *errno* or the *code* parameter::
1203 if (open(filename, O_RDONLY) < 0)
1204 xo_err(1, "cannot open file '%s'", filename);
1207 .. index:: xo_error_h
1208 .. index:: xo_error_hv
1209 .. index:: xo_errorn
1210 .. index:: xo_errorn_h
1211 .. index:: xo_errorn_hv
1216 .. c:function:: void xo_error (const char *fmt, ...)
1218 :param fmt: Format string
1219 :type fmt: const char *
1222 .. c:function:: void xo_error_h (xo_handle_t *xop, const char *fmt, ...)
1224 :param xop: libxo handle pointer
1225 :type xop: xo_handle_t *
1226 :param fmt: Format string
1227 :type fmt: const char *
1230 .. c:function:: void xo_error_hv (xo_handle_t *xop, const char *fmt, va_list vap)
1232 :param xop: libxo handle pointer
1233 :type xop: xo_handle_t *
1234 :param fmt: Format string
1235 :type fmt: const char *
1236 :param vap: variadic arguments
1240 .. c:function:: void xo_errorn (const char *fmt, ...)
1242 :param fmt: Format string
1243 :type fmt: const char *
1246 .. c:function:: void xo_errorn_h (xo_handle_t *xop, const char *fmt, ...)
1248 :param xop: libxo handle pointer
1249 :type xop: xo_handle_t *
1250 :param fmt: Format string
1251 :type fmt: const char *
1254 .. c:function:: void xo_errorn_hv (xo_handle_t *xop, int need_newline, const char *fmt, va_list vap)
1256 :param xop: libxo handle pointer
1257 :type xop: xo_handle_t *
1258 :param need_newline: boolean indicating need for trailing newline
1259 :type need_newline: int
1260 :param fmt: Format string
1261 :type fmt: const char *
1262 :param vap: variadic arguments
1266 The `xo_error` function can be used for generic errors that should
1267 be reported over the handle, rather than to stderr. The `xo_error`
1268 function behaves like `xo_err` for TEXT and HTML output styles, but
1269 puts the error into XML or JSON elements::
1272 xo_error("Does not %s", "compute");
1274 <error><message>Does not compute</message></error>
1276 "error": { "message": "Does not compute" }
1278 The `xo_error_h` and `xo_error_hv` add a handle object and a
1279 variadic-ized parameter to the signature, respectively.
1281 The `xo_errorn` function supplies a newline at the end the error
1282 message if the format string does not include one. The
1283 `xo_errorn_h` and `xo_errorn_hv` functions add a handle object and
1284 a variadic-ized parameter to the signature, respectively. The
1285 `xo_errorn_hv` function also adds a boolean to indicate the need for
1288 .. index:: xo_no_setlocale
1294 .. c:function:: void xo_no_setlocale (void)
1296 libxo automatically initializes the locale based on setting of the
1297 environment variables LC_CTYPE, LANG, and LC_ALL. The first of this
1298 list of variables is used and if none of the variables, the locale
1299 defaults to "UTF-8". The caller may wish to avoid this behavior,
1300 and can do so by calling the `xo_no_setlocale` function.
1302 Emitting syslog Messages
1303 ------------------------
1305 syslog is the system logging facility used throughout the unix world.
1306 Messages are sent from commands, applications, and daemons to a
1307 hierarchy of servers, where they are filtered, saved, and forwarded
1308 based on configuration behaviors.
1310 syslog is an older protocol, originally documented only in source
1311 code. By the time :RFC:`3164` published, variation and mutation left the
1312 leading "<pri>" string as only common content. :RFC:`5424` defines a new
1313 version (version 1) of syslog and introduces structured data into the
1314 messages. Structured data is a set of name/value pairs transmitted
1315 distinctly alongside the traditional text message, allowing filtering
1316 on precise values instead of regular expressions.
1318 These name/value pairs are scoped by a two-part identifier; an
1319 enterprise identifier names the party responsible for the message
1320 catalog and a name identifying that message. `Enterprise IDs`_ are
1321 defined by IANA, the Internet Assigned Numbers Authority.
1324 https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers
1326 Use the `xo_set_syslog_enterprise_id` function to set the Enterprise
1329 The message name should follow the conventions in
1330 :ref:`good-field-names`\ , as should the fields within the message::
1332 /* Both of these calls are optional */
1333 xo_set_syslog_enterprise_id(32473);
1334 xo_open_log("my-program", 0, LOG_DAEMON);
1336 /* Generate a syslog message */
1337 xo_syslog(LOG_ERR, "upload-failed",
1338 "error <%d> uploading file '{:filename}' "
1339 "as '{:target/%s:%s}'",
1340 code, filename, protocol, remote);
1342 xo_syslog(LOG_INFO, "poofd-invalid-state",
1343 "state {:current/%u} is invalid {:connection/%u}",
1346 The developer should be aware that the message name may be used in the
1347 future to allow access to further information, including
1348 documentation. Care should be taken to choose quality, descriptive
1353 Priority, Facility, and Flags
1354 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1356 The `xo_syslog`, `xo_vsyslog`, and `xo_open_log` functions
1357 accept a set of flags which provide the priority of the message, the
1358 source facility, and some additional features. These values are OR'd
1359 together to create a single integer argument::
1361 xo_syslog(LOG_ERR | LOG_AUTH, "login-failed",
1362 "Login failed; user '{:user}' from host '{:address}'",
1365 These values are defined in <syslog.h>.
1367 The priority value indicates the importance and potential impact of
1370 ============= =======================================================
1371 Priority Description
1372 ============= =======================================================
1373 LOG_EMERG A panic condition, normally broadcast to all users
1374 LOG_ALERT A condition that should be corrected immediately
1375 LOG_CRIT Critical conditions
1376 LOG_ERR Generic errors
1377 LOG_WARNING Warning messages
1378 LOG_NOTICE Non-error conditions that might need special handling
1379 LOG_INFO Informational messages
1380 LOG_DEBUG Developer-oriented messages
1381 ============= =======================================================
1383 The facility value indicates the source of message, in fairly generic
1386 =============== =======================================================
1387 Facility Description
1388 =============== =======================================================
1389 LOG_AUTH The authorization system (e.g. :manpage:`login(1)`)
1390 LOG_AUTHPRIV As LOG_AUTH, but logged to a privileged file
1391 LOG_CRON The cron daemon: :manpage:`cron(8)`
1392 LOG_DAEMON System daemons, not otherwise explicitly listed
1393 LOG_FTP The file transfer protocol daemons
1394 LOG_KERN Messages generated by the kernel
1395 LOG_LPR The line printer spooling system
1396 LOG_MAIL The mail system
1397 LOG_NEWS The network news system
1398 LOG_SECURITY Security subsystems, such as :manpage:`ipfw(4)`
1399 LOG_SYSLOG Messages generated internally by :manpage:`syslogd(8)`
1400 LOG_USER Messages generated by user processes (default)
1401 LOG_UUCP The uucp system
1402 LOG_LOCAL0..7 Reserved for local use
1403 =============== =======================================================
1405 In addition to the values listed above, xo_open_log accepts a set of
1406 addition flags requesting specific logging behaviors:
1408 ============ ====================================================
1410 ============ ====================================================
1411 LOG_CONS If syslogd fails, attempt to write to /dev/console
1412 LOG_NDELAY Open the connection to :manpage:`syslogd(8)` immediately
1413 LOG_PERROR Write the message also to standard error output
1414 LOG_PID Log the process id with each message
1415 ============ ====================================================
1417 .. index:: xo_syslog
1422 .. c:function:: void xo_syslog (int pri, const char *name, const char *fmt, ...)
1424 :param int pri: syslog priority
1425 :param name: Name of the syslog event
1426 :type name: const char *
1427 :param fmt: Format string, followed by arguments
1428 :type fmt: const char *
1431 Use the `xo_syslog` function to generate syslog messages by calling
1432 it with a log priority and facility, a message name, a format
1433 string, and a set of arguments. The priority/facility argument are
1434 discussed above, as is the message name.
1436 The format string follows the same conventions as `xo_emit`'s format
1437 string, with each field being rendered as an SD-PARAM pair::
1439 xo_syslog(LOG_ERR, "poofd-missing-file",
1440 "'{:filename}' not found: {:error/%m}", filename);
1442 ... [poofd-missing-file@32473 filename="/etc/poofd.conf"
1443 error="Permission denied"] '/etc/poofd.conf' not
1444 found: Permission denied
1449 .. index:: xo_vsyslog
1454 .. c:function:: void xo_vsyslog (int pri, const char *name, const char *fmt, va_list vap)
1456 :param int pri: syslog priority
1457 :param name: Name of the syslog event
1458 :type name: const char *
1459 :param fmt: Format string
1460 :type fmt: const char *
1461 :param va_list vap: Variadic argument list
1464 xo_vsyslog is identical in function to xo_syslog, but takes the set of
1465 arguments using a va_list::
1469 my_log (const char *name, const char *fmt, ...)
1473 xo_vsyslog(LOG_ERR, name, fmt, vap);
1477 .. index:: xo_open_log
1482 .. c:function:: void xo_open_log (const char *ident, int logopt, int facility)
1485 :type indent: const char *
1486 :param int logopt: Bit field containing logging options
1487 :param int facility:
1490 xo_open_log functions similar to :manpage:`openlog(3)`, allowing
1491 customization of the program name, the log facility number, and the
1492 additional option flags described in :ref:`syslog-details`.
1494 .. index:: xo_close_log
1499 .. c:function:: void xo_close_log (void)
1501 The `xo_close_log` function is similar to :manpage:`closelog(3)`,
1502 closing the log file and releasing any associated resources.
1504 .. index:: xo_set_logmask
1509 .. c:function:: int xo_set_logmask (int maskpri)
1511 :param int maskpri: the log priority mask
1512 :returns: The previous log priority mask
1514 The `xo_set_logmask` function is similar to :manpage:`setlogmask(3)`,
1515 restricting the set of generated log event to those whose associated
1516 bit is set in maskpri. Use `LOG_MASK(pri)` to find the appropriate bit,
1517 or `LOG_UPTO(toppri)` to create a mask for all priorities up to and
1521 setlogmask(LOG_UPTO(LOG_WARN));
1523 .. index:: xo_set_syslog_enterprise_id
1525 xo_set_syslog_enterprise_id
1526 +++++++++++++++++++++++++++
1528 .. c:function:: void xo_set_syslog_enterprise_id (unsigned short eid)
1530 Use the `xo_set_syslog_enterprise_id` to supply a platform- or
1531 application-specific enterprise id. This value is used in any future
1534 Ideally, the operating system should supply a default value via the
1535 "kern.syslog.enterprise_id" sysctl value. Lacking that, the
1536 application should provide a suitable value.
1538 Enterprise IDs are administered by IANA, the Internet Assigned Number
1539 Authority. The complete list is EIDs on their web site::
1541 https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers
1543 New EIDs can be requested from IANA using the following page::
1545 http://pen.iana.org/pen/PenApplication.page
1547 Each software development organization that defines a set of syslog
1548 messages should register their own EID and use that value in their
1549 software to ensure that messages can be uniquely identified by the
1550 combination of EID + message name.
1552 Creating Custom Encoders
1553 ------------------------
1555 The number of encoding schemes in current use is staggering, with new
1556 and distinct schemes appearing daily. While libxo provide XML, JSON,
1557 HMTL, and text natively, there are requirements for other encodings.
1559 Rather than bake support for all possible encoders into libxo, the API
1560 allows them to be defined externally. libxo can then interfaces with
1561 these encoding modules using a simplistic API. libxo processes all
1562 functions calls, handles state transitions, performs all formatting,
1563 and then passes the results as operations to a customized encoding
1564 function, which implements specific encoding logic as required. This
1565 means your encoder doesn't need to detect errors with unbalanced
1566 open/close operations but can rely on libxo to pass correct data.
1568 By making a simple API, libxo internals are not exposed, insulating the
1569 encoder and the library from future or internal changes.
1571 The three elements of the API are:
1577 The following sections provide details about these topics.
1581 libxo source contains an encoder for Concise Binary Object
1582 Representation, aka CBOR (:RFC:`7049`), which can be used as an
1583 example for the API for other encoders.
1588 Encoders can be registered statically or discovered dynamically.
1589 Applications can choose to call the `xo_encoder_register` function
1590 to explicitly register encoders, but more typically they are built as
1591 shared libraries, placed in the libxo/extensions directory, and loaded
1592 based on name. libxo looks for a file with the name of the encoder
1593 and an extension of ".enc". This can be a file or a symlink to the
1594 shared library file that supports the encoder::
1596 % ls -1 lib/libxo/extensions/*.enc
1597 lib/libxo/extensions/cbor.enc
1598 lib/libxo/extensions/test.enc
1600 Encoder Initialization
1601 ~~~~~~~~~~~~~~~~~~~~~~
1603 Each encoder must export a symbol used to access the library, which
1604 must have the following signature::
1606 int xo_encoder_library_init (XO_ENCODER_INIT_ARGS);
1608 `XO_ENCODER_INIT_ARGS` is a macro defined in "xo_encoder.h" that defines
1609 an argument called "arg", a pointer of the type
1610 `xo_encoder_init_args_t`. This structure contains two fields:
1612 - `xei_version` is the version number of the API as implemented
1613 within libxo. This version is currently as 1 using
1614 `XO_ENCODER_VERSION`. This number can be checked to ensure
1615 compatibility. The working assumption is that all versions should
1616 be backward compatible, but each side may need to accurately know
1617 the version supported by the other side. `xo_encoder_library_init`
1618 can optionally check this value, and must then set it to the version
1619 number used by the encoder, allowing libxo to detect version
1620 differences and react accordingly. For example, if version 2 adds
1621 new operations, then libxo will know that an encoding library that
1622 set `xei_version` to 1 cannot be expected to handle those new
1625 - xei_handler must be set to a pointer to a function of type
1626 `xo_encoder_func_t`, as defined in "xo_encoder.h". This function
1627 takes a set of parameters:
1628 - xop is a pointer to the opaque `xo_handle_t` structure
1629 - op is an integer representing the current operation
1630 - name is a string whose meaning differs by operation
1631 - value is a string whose meaning differs by operation
1632 - private is an opaque structure provided by the encoder
1634 Additional arguments may be added in the future, so handler functions
1635 should use the `XO_ENCODER_HANDLER_ARGS` macro. An appropriate
1636 "extern" declaration is provided to help catch errors.
1638 Once the encoder initialization function has completed processing, it
1639 should return zero to indicate that no error has occurred. A non-zero
1640 return code will cause the handle initialization to fail.
1645 The encoder API defines a set of operations representing the
1646 processing model of libxo. Content is formatted within libxo, and
1647 callbacks are made to the encoder's handler function when data is
1648 ready to be processed:
1650 ======================= =======================================
1651 Operation Meaning (Base function)
1652 ======================= =======================================
1653 XO_OP_CREATE Called when the handle is created
1654 XO_OP_OPEN_CONTAINER Container opened (xo_open_container)
1655 XO_OP_CLOSE_CONTAINER Container closed (xo_close_container)
1656 XO_OP_OPEN_LIST List opened (xo_open_list)
1657 XO_OP_CLOSE_LIST List closed (xo_close_list)
1658 XO_OP_OPEN_LEAF_LIST Leaf list opened (xo_open_leaf_list)
1659 XO_OP_CLOSE_LEAF_LIST Leaf list closed (xo_close_leaf_list)
1660 XO_OP_OPEN_INSTANCE Instance opened (xo_open_instance)
1661 XO_OP_CLOSE_INSTANCE Instance closed (xo_close_instance)
1662 XO_OP_STRING Field with Quoted UTF-8 string
1663 XO_OP_CONTENT Field with content
1664 XO_OP_FINISH Finish any pending output
1665 XO_OP_FLUSH Flush any buffered output
1666 XO_OP_DESTROY Clean up resources
1667 XO_OP_ATTRIBUTE An attribute name/value pair
1668 XO_OP_VERSION A version string
1669 ======================= =======================================
1671 For all the open and close operations, the name parameter holds the
1672 name of the construct. For string, content, and attribute operations,
1673 the name parameter is the name of the field and the value parameter is
1674 the value. "string" are differentiated from "content" to allow differing
1675 treatment of true, false, null, and numbers from real strings, though
1676 content values are formatted as strings before the handler is called.
1677 For version operations, the value parameter contains the version.
1679 All strings are encoded in UTF-8.