LIBXO(3)

πŸ“¦
version 1.7.5 Β· 2 versions
, in epel 9, fedora 43, fedora 44, nixpkgs unstable

πŸ’– LIBXO(3) β€” the list & instance era πŸ’–

okay bestie, sit down, hydrate, and let me tell you about the libxo list functions β€” yes, all sixteen of them, we're doing this, no skipping 🫢


✨ NAME ✨

xo_open_list, xo_open_list_h, xo_open_list_hd, xo_open_list_d, xo_open_instance, xo_open_instance_h, xo_open_instance_hd, xo_open_instance_d, xo_close_instance, xo_close_instance_h, xo_close_instance_hd, xo_close_instance_d, xo_close_list, xo_close_list_h, xo_close_list_hd, xo_close_list_d β€” open and close lists and instances πŸ’…


πŸ“š LIBRARY πŸ“š

library β€œlibxo” β€” she's the moment, she's the icon πŸ‘‘


🌸 SYNOPSIS 🌸

#include <libxo/xo.h>

xo_ssize_t
xo_open_list_h(xo_handle_t *xop, const char *name);

xo_ssize_t
xo_open_list(const char *name);

xo_ssize_t
xo_open_list_hd(xo_handle_t *xop, const char *name);

xo_ssize_t
xo_open_list_d(const char *name);

xo_ssize_t
xo_open_instance_h(xo_handle_t *xop, const char *name);

xo_ssize_t
xo_open_instance(const char *name);

xo_ssize_t
xo_open_instance_hd(xo_handle_t *xop, const char *name);

xo_ssize_t
xo_open_instance_d(const char *name);

xo_ssize_t
xo_close_instance_h(xo_handle_t *xop, const char *name);

xo_ssize_t
xo_close_instance(const char *name);

xo_ssize_t
xo_close_instance_hd(xo_handle_t *xop);

xo_ssize_t
xo_close_instance_d(void);

xo_ssize_t
xo_close_list_h(xo_handle_t *xop, const char *name);

xo_ssize_t
xo_close_list(const char *name);

xo_ssize_t
xo_close_list_hd(xo_handle_t *xop);

xo_ssize_t
xo_close_list_d(void);

πŸ¦‹ DESCRIPTION πŸ¦‹

so. lists are sequences of instances of homogeneous data objects. that's the vibe. to represent them in our output styles you need two distinct levels of calls β€” like, two layers of the same energy. you gotta make calls to open and close a list, and then for each instance of data inside that list, you make calls to open and close that instance. two levels, no shortcuts, periodt ✨

the name you give to all those calls must be identical β€” like, every single one, no cap. and it is strongly suggested that the name be singular, not plural, as a matter of style and usage expectations. yes bestie, singular. that's the look πŸ’…

a list is a set of one or more instances that appear under the same parent. the instances contain details about a specific object. you can lowkey think of instances as objects or records. one call is needed to open and close the list, while a distinct call is needed to open and close each instance of the list:

xo_open_list("item");

for (ip = list; ip->i_title; ip++) {
    xo_open_instance("item");
    xo_emit("{L:Item} '{:name/%s}':\n", ip->i_title);
    xo_close_instance("item");
}

xo_close_list("item");

getting the list and instance calls correct is critical to the proper generation of XML and JSON data. like, do not fumble this one, it's giving load-bearing 🫠

EXAMPLE:
    xo_open_list("user");
    for (i = 0; i < num_users; i++) {
        xo_open_instance("user");
        xo_emit("{k:name}:{:uid/%u}:{:gid/%u}:{:home}\n",
                pw[i].pw_name, pw[i].pw_uid,
                pw[i].pw_gid, pw[i].pw_dir);
        xo_close_instance("user");
    }
    xo_close_list("user");
TEXT:
    phil:1001:1001:/home/phil
    pallavi:1002:1002:/home/pallavi
XML:
    <user>
        <name>phil</name>
        <uid>1001</uid>
        <gid>1001</gid>
        <home>/home/phil</home>
    </user>
    <user>
        <name>pallavi</name>
        <uid>1002</uid>
        <gid>1002</gid>
        <home>/home/pallavi</home>
    </user>
JSON:
    user: [
        {
            "name": "phil",
            "uid": 1001,
            "gid": 1001,
            "home": "/home/phil",
        },
        {
            "name": "pallavi",
            "uid": 1002,
            "gid": 1002,
            "home": "/home/pallavi",
        }
    ]

πŸ“ LEAF LISTS πŸ“

okay so, in contrast to a list of instances, a "leaf list" is a list of simple values. not objects, just lil guys 🌱. to emit a leaf list, call the xo_emit() function using the "l" modifier:

for (ip = list; ip->i_title; ip++) {
    xo_emit("{Lwc:Item}{l:item}\n", ip->i_title);
}

the name of the field must match the name of the leaf list. matching names or it's not gonna eat, iykyk πŸ’€

in JSON, leaf lists are rendered as arrays of values. in XML, they are rendered as multiple leaf elements. iconic behaviour honestly 🌈

JSON:
    "item": "hammer", "nail"
XML:
    <item>hammer</item>
    <item>nail</item>

πŸ‘€ SEE ALSO πŸ‘€

xo_emit(3), libxo(3) β€” go read those too, they're besties with this page 🫢


πŸŽ€ HISTORY πŸŽ€

the libxo library first appeared in FreeBSD 11.0. a whole era began πŸ’–


🌟 AUTHORS 🌟

libxo was written by Phil Shafer <phil@freebsd.org>. legend behaviour, fr fr πŸ‘‘


πŸ“– ADDITIONAL DOCUMENTATION πŸ“–

FreeBSD uses libxo version 1.7.5. complete documentation can be found on github:

https://juniper.github.io/libxo/1.7.5/html/index.html

libxo lives on github as:

https://github.com/Juniper/libxo

the latest release of libxo is available at:

https://github.com/Juniper/libxo/releases

⭐ HISTORY ⭐

the libxo library was added in FreeBSD 11.0. (yes, this section shows up twice, and yes, both times are valid β€” the manpage said what it said and we're not editing her πŸ’…)


✍️ AUTHOR ✍️

Phil Shafer 🌸


this page is brought to you by the Debian crew, dated December 4, 2014, filed under LIBXO(3). and that's the whole thing bestie β€” go open some lists, close some instances, and stay singular πŸ’–βœ¨πŸŽ€πŸ¦‹
πŸ“¦ where this page comes from