.. index:: --libxo, xo .. _xo: The "xo" Utility ================ The `xo` utility allows command line access to the functionality of the libxo library. Using `xo`, shell scripts can emit XML, JSON, and HTML using the same commands that emit text output. The style of output can be selected using a specific option: "-X" for XML, "-J" for JSON, "-H" for HTML, or "-T" for TEXT, which is the default. The "--style <style>" option can also be used. The standard set of "--libxo" options are available (see :ref:`options`), as well as the :ref:`LIBXO_OPTIONS <libxo-options>` environment variable. The `xo` utility accepts a format string suitable for `xo_emit` and a set of zero or more arguments used to supply data for that string:: xo "The {k:name} weighs {:weight/%d} pounds.\n" fish 6 TEXT: The fish weighs 6 pounds. XML: <name>fish</name> <weight>6</weight> JSON: "name": "fish", "weight": 6 HTML: <div class="line"> <div class="text">The </div> <div class="data" data-tag="name">fish</div> <div class="text"> weighs </div> <div class="data" data-tag="weight">6</div> <div class="text"> pounds.</div> </div> The `--wrap $path` option can be used to wrap emitted content in a specific hierarchy. The path is a set of hierarchical names separated by the '/' character:: xo --wrap top/a/b/c '{:tag}' value XML: <top> <a> <b> <c> <tag>value</tag> </c> </b> </a> </top> JSON: "top": { "a": { "b": { "c": { "tag": "value" } } } } The `--open $path` and `--close $path` can be used to emit hierarchical information without the matching close and open tag. This allows a shell script to emit open tags, data, and then close tags. The `--depth` option may be used to set the depth for indentation. The `--leading-xpath` may be used to prepend data to the XPath values used for HTML output style:: EXAMPLE: #!/bin/sh xo --open top/data xo --depth 2 '{:tag}' value xo --close top/data XML: <top> <data> <tag>value</tag> </data> </top> JSON: "top": { "data": { "tag": "value" } } When making partial lines of output (where the format string does not include a newline), use the `--continuation` option to let secondary invocations know they are adding data to an existing line. When emitting a series of objects, use the `--not-first` option to ensure that any details from the previous object (e.g. commas in JSON) are handled correctly. Use the `--top-wrap` option to ensure any top-level object details are handled correctly, e.g. wrap the entire output in a top-level set of braces for JSON output. :: EXAMPLE: #!/bin/sh xo --top-wrap --open top/data xo --depth 2 'First {:tag} ' value1 xo --depth 2 --continuation 'and then {:tag}\n' value2 xo --top-wrap --close top/data TEXT: First value1 and then value2 HTML: <div class="line"> <div class="text">First </div> <div class="data" data-tag="tag">value1</div> <div class="text"> </div> <div class="text">and then </div> <div class="data" data-tag="tag">value2</div> </div> XML: <top> <data> <tag>value1</tag> <tag>value2</tag> </data> </top> JSON: { "top": { "data": { "tag": "value1", "tag": "value2" } } } Lists and Instances ------------------- A "*list*" is set of one or more instances that appear under the same parent. The instances contain details about a specific object. One can think of instances as objects or records. A call is needed to open and close the list, while a distinct call is needed to open and close each instance of the list. Use the `--open-list` and `--open-instances` to open lists and instances. Use the `--close-list` and `--close-instances` to close them. Each of these options take a `name` parameter, providing the name of the list and instance. In the following example, a list named "machine" is created with three instances:: opts="--json" xo $opts --open-list machine NF= for name in red green blue; do xo $opts --depth 1 $NF --open-instance machine xo $opts --depth 2 "Machine {k:name} has {:memory}\n" $name 55 xo $opts --depth 1 --close-instance machine NF=--not-first done xo $opts $NF --close-list machine The normal `libxo` functions use a state machine to help these transitions, but since each `xo` command is invoked independent of the previous calls, the state must be passed in explicitly via these command line options. The `--instance` option can be used to treat a single `xo` invocation as an instance with the given set of fields:: % xo --libxo:XP --instance foo 'The {:product} is {:status}\n' stereo "in route" <foo> <product>stereo</product> <status>in route</status> </foo> Command Line Options -------------------- :: Usage: xo [options] format [fields] --close <path> Close tags for the given path --close-instance <name> Close an open instance name --close-list <name> Close an open list name --continuation OR -C Output belongs on same line as previous output --depth <num> Set the depth for pretty printing --help Display this help text --html OR -H Generate HTML output --instance OR -I <name> Wrap in an instance of the given name --json OR -J Generate JSON output --leading-xpath <path> Add a prefix to generated XPaths (HTML) --not-first Indicate this object is not the first (JSON) --open <path> Open tags for the given path --open-instance <name> Open an instance given by name --open-list <name> Open a list given by name --option <opts> -or -O <opts> Give formatting options --pretty OR -p Make 'pretty' output (add indent, newlines) --style <style> Generate given style (xml, json, text, html) --text OR -T Generate text output (the default style) --top-wrap Generate a top-level object wrapper (JSON) --version Display version information --warn OR -W Display warnings in text on stderr --warn-xml Display warnings in xml on stdout --wrap <path> Wrap output in a set of containers --xml OR -X Generate XML output --xpath Add XPath data to HTML output) Example ------- :: % xo 'The {:product} is {:status}\n' stereo "in route" The stereo is in route % xo -p -X 'The {:product} is {:status}\n' stereo "in route" <product>stereo</product> <status>in route</status> % xo --libxo xml,pretty 'The {:product} is {:status}\n' stereo "in route" <product>stereo</product> <status>in route</status>