6 This section gives an overview of encoders, details on the encoders
7 that ship with libxo, and documentation for developers of future
13 The libxo library contains software to generate four "built-in"
14 formats: text, XML, JSON, and HTML. These formats are common and
15 useful, but there are other common and useful formats that users will
16 want, and including them all in the libxo software would be difficult
19 To allow support for additional encodings, libxo includes a
20 "pluggable" extension mechanism for dynamically loading new encoders.
21 libxo-based applications can automatically use any installed encoder.
23 Use the "encoder=XXX" option to access encoders. The following
24 example uses the "cbor" encoder, saving the output into a file::
26 df --libxo encoder=cbor > df-output.cbor
28 Encoders can support specific options that can be accessed by
29 following the encoder name with a colon (':') or a plus sign ('+') and
30 one of more options, separated by the same character::
32 df --libxo encoder=csv+path=filesystem+leaf=name+no-header
33 df --libxo encoder=csv:path=filesystem:leaf=name:no-header
35 These examples instructs libxo to load the "csv" encoder and pass the
42 Each of these option is interpreted by the encoder, and all such
43 options names and semantics are specific to the particular encoder.
44 Refer to the intended encoder for documentation on its options.
46 The string "@" can be used in place of the string "encoder=".
48 df --libxo @csv:no-header
52 CSV - Comma Separated Values
53 ----------------------------
55 libxo ships with a custom encoder for "CSV" files, a common format for
56 comma separated values. The output of the CSV encoder can be loaded
57 directly into spreadsheets or similar applications.
59 A standard for CSV files is provided in :RFC:`4180`, but since the
60 format predates that standard by decades, there are many minor
61 differences in CSV file consumers and their expectations. The CSV
62 encoder has a number of options to tailor output to those
65 Consider the following XML::
67 % list-items --libxo xml,pretty
71 <sku test3="value3" key="key">GRO-000-415</sku>
72 <name key="key">gum</name>
74 <in-stock>54</in-stock>
75 <on-order>10</on-order>
78 <sku test3="value3" key="key">HRD-000-212</sku>
79 <name key="key">rope</name>
81 <in-stock>4</in-stock>
82 <on-order>2</on-order>
85 <sku test3="value3" key="key">HRD-000-517</sku>
86 <name key="key">ladder</name>
88 <in-stock>2</in-stock>
89 <on-order>1</on-order>
94 This output is a list of `instances` (named "item"), each containing a
95 set of `leafs` ("sku", "name", etc).
97 The CSV encoder will emit the leaf values in this output as `fields`
98 inside a CSV `record`, which is a line containing a set of
99 comma-separated values::
101 % list-items --libxo encoder=csv
102 sku,name,sold,in-stock,on-order
103 GRO-000-415,gum,1412,54,10
104 HRD-000-212,rope,85,4,2
105 HRD-000-517,ladder,0,2,1
107 Be aware that since the CSV encoder looks for data instances, when
108 used with :ref:`xo`, the `--instance` option will be needed::
110 % xo --libxo encoder=csv --instance foo 'The {:product} is {:status}\n' stereo "in route"
119 By default, the CSV encoder will attempt to emit any list instance
120 generated by the application. In some cases, this may be
121 unacceptable, and a specific list may be desired.
123 Use the "path" option to limit the processing of output to a specific
124 hierarchy. The path should be one or more names of containers or
127 For example, if the "list-items" application generates other lists,
128 the user can give "path=top/data/item" as a path::
130 % list-items --libxo encoder=csv:path=top/data/item
131 sku,name,sold,in-stock,on-order
132 GRO-000-415,gum,1412,54,10
133 HRD-000-212,rope,85,4,2
134 HRD-000-517,ladder,0,2,1
136 Paths are "relative", meaning they need not be a complete set
137 of names to the list. This means that "path=item" may be sufficient
138 for the above example.
145 The CSV encoding requires that all lines of output have the same
146 number of fields with the same order. In contrast, XML and JSON allow
147 any order (though libxo forces key leafs to appear before other
150 To maintain a consistent set of fields inside the CSV file, the same
151 set of leafs must be selected from each list item. By default, the
152 CSV encoder records the set of leafs that appear in the first list
153 instance it processes, and extract only those leafs from future
154 instances. If the first instance is missing a leaf that is desired by
155 the consumer, the "leaf" option can be used to ensure that an empty
156 value is recorded for instances that lack a particular leaf.
158 The "leafs" option can also be used to exclude leafs, limiting the
159 output to only those leafs provided.
161 In addition, the order of the output fields follows the order in which
162 the leafs are listed. "leafs=one.two" and "leafs=two.one" give
165 So the "leafs" option can be used to expand, limit, and order the set
168 The value of the leafs option should be one or more leaf names,
169 separated by a period (".")::
171 % list-items --libxo encoder=csv:leafs=sku.on-order
176 % list-items -libxo encoder=csv:leafs=on-order.sku
182 Note that since libxo uses terminology from YANG (:RFC:`7950`), the
183 data modeling language for NETCONF (:RFC:`6241`), which uses "leafs"
184 as the plural form of "leaf". libxo follows that convention.
188 The `no-header` Option
189 ~~~~~~~~~~~~~~~~~~~~~~
191 CSV files typical begin with a line that defines the fields included
192 in that file, in an attempt to make the contents self-defining::
194 sku,name,sold,in-stock,on-order
195 GRO-000-415,gum,1412,54,10
196 HRD-000-212,rope,85,4,2
197 HRD-000-517,ladder,0,2,1
199 There is no reliable mechanism for determining whether this header
200 line is included, so the consumer must make an assumption.
202 The csv encoder defaults to producing the header line, but the
203 "no-header" option can be included to avoid the header line.
207 The `no-quotes` Option
208 ~~~~~~~~~~~~~~~~~~~~~~
210 :RFC:`4180` specifies that fields containing spaces should be quoted, but
211 many CSV consumers do not handle quotes. The "no-quotes" option
212 instruct the CSV encoder to avoid the use of quotes.
219 :RFC:`4180` defines the end-of-line marker as a carriage return
220 followed by a newline. This `CRLF` convention dates from the distant
221 past, but its use was anchored in the 1980s by the `DOS` operating
224 The CSV encoder defaults to using the standard Unix end-of-line
225 marker, a simple newline. Use the "dos" option to use the `CRLF`
231 The encoder API consists of three distinct phases:
233 - loading the encoder
234 - initializing the encoder
235 - feeding operations to the encoder
237 To load the encoder, libxo will open a shared library named:
239 ${prefix}/lib/libxo/encoder/${name}.enc
241 This file is typically a symbolic link to a dynamic library, suitable
242 for `dlopen`(). libxo looks for a symbol called
243 `xo_encoder_library_init` inside that library and calls it with the
244 arguments defined in the header file "xo_encoder.h". This function
245 should look as follows::
248 xo_encoder_library_init (XO_ENCODER_INIT_ARGS)
250 arg->xei_version = XO_ENCODER_VERSION;
251 arg->xei_handler = test_handler;
256 Several features here allow for future compatibility: the macro
257 XO_ENCODER_INIT_ARGS allows the arguments to this function change over
258 time, and the XO_ENCODER_VERSION allows the library to tell libxo
259 which version of the API it was compiled with.
261 The function places in xei_handler should be have the signature::
264 test_handler (XO_ENCODER_HANDLER_ARGS)
268 This function will be called with the "op" codes defined in
269 "xo_encoder.h". Each op code represents a distinct event in the libxo
270 processing model. For example OP_OPEN_CONTAINER tells the encoder
271 that a new container has been opened, and the encoder can behave in an