1983afe33SPhil Shafer.. index:: --libxo, xo 2*76afb20cSPhil Shafer.. _xo: 3983afe33SPhil Shafer 4983afe33SPhil ShaferThe "xo" Utility 5983afe33SPhil Shafer================ 6983afe33SPhil Shafer 7983afe33SPhil ShaferThe `xo` utility allows command line access to the functionality of 8983afe33SPhil Shaferthe libxo library. Using `xo`, shell scripts can emit XML, JSON, and 9983afe33SPhil ShaferHTML using the same commands that emit text output. 10983afe33SPhil Shafer 11983afe33SPhil ShaferThe style of output can be selected using a specific option: "-X" for 12983afe33SPhil ShaferXML, "-J" for JSON, "-H" for HTML, or "-T" for TEXT, which is the 13983afe33SPhil Shaferdefault. The "--style <style>" option can also be used. The standard 14983afe33SPhil Shaferset of "--libxo" options are available (see :ref:`options`), as well 15*76afb20cSPhil Shaferas the :ref:`LIBXO_OPTIONS <libxo-options>` environment variable. 16983afe33SPhil Shafer 17983afe33SPhil ShaferThe `xo` utility accepts a format string suitable for `xo_emit` and 18983afe33SPhil Shafera set of zero or more arguments used to supply data for that string:: 19983afe33SPhil Shafer 20983afe33SPhil Shafer xo "The {k:name} weighs {:weight/%d} pounds.\n" fish 6 21983afe33SPhil Shafer 22983afe33SPhil Shafer TEXT: 23983afe33SPhil Shafer The fish weighs 6 pounds. 24*76afb20cSPhil Shafer 25983afe33SPhil Shafer XML: 26983afe33SPhil Shafer <name>fish</name> 27983afe33SPhil Shafer <weight>6</weight> 28*76afb20cSPhil Shafer 29983afe33SPhil Shafer JSON: 30983afe33SPhil Shafer "name": "fish", 31983afe33SPhil Shafer "weight": 6 32*76afb20cSPhil Shafer 33983afe33SPhil Shafer HTML: 34983afe33SPhil Shafer <div class="line"> 35983afe33SPhil Shafer <div class="text">The </div> 36983afe33SPhil Shafer <div class="data" data-tag="name">fish</div> 37983afe33SPhil Shafer <div class="text"> weighs </div> 38983afe33SPhil Shafer <div class="data" data-tag="weight">6</div> 39983afe33SPhil Shafer <div class="text"> pounds.</div> 40983afe33SPhil Shafer </div> 41983afe33SPhil Shafer 42983afe33SPhil ShaferThe `--wrap $path` option can be used to wrap emitted content in a 43983afe33SPhil Shaferspecific hierarchy. The path is a set of hierarchical names separated 44983afe33SPhil Shaferby the '/' character:: 45983afe33SPhil Shafer 46983afe33SPhil Shafer xo --wrap top/a/b/c '{:tag}' value 47983afe33SPhil Shafer 48983afe33SPhil Shafer XML: 49983afe33SPhil Shafer <top> 50983afe33SPhil Shafer <a> 51983afe33SPhil Shafer <b> 52983afe33SPhil Shafer <c> 53983afe33SPhil Shafer <tag>value</tag> 54983afe33SPhil Shafer </c> 55983afe33SPhil Shafer </b> 56983afe33SPhil Shafer </a> 57983afe33SPhil Shafer </top> 58*76afb20cSPhil Shafer 59983afe33SPhil Shafer JSON: 60983afe33SPhil Shafer "top": { 61983afe33SPhil Shafer "a": { 62983afe33SPhil Shafer "b": { 63983afe33SPhil Shafer "c": { 64983afe33SPhil Shafer "tag": "value" 65983afe33SPhil Shafer } 66983afe33SPhil Shafer } 67983afe33SPhil Shafer } 68983afe33SPhil Shafer } 69983afe33SPhil Shafer 70983afe33SPhil ShaferThe `--open $path` and `--close $path` can be used to emit 71983afe33SPhil Shaferhierarchical information without the matching close and open 72983afe33SPhil Shafertag. This allows a shell script to emit open tags, data, and 73983afe33SPhil Shaferthen close tags. The `--depth` option may be used to set the 74983afe33SPhil Shaferdepth for indentation. The `--leading-xpath` may be used to 75983afe33SPhil Shaferprepend data to the XPath values used for HTML output style:: 76983afe33SPhil Shafer 77*76afb20cSPhil Shafer EXAMPLE: 78983afe33SPhil Shafer #!/bin/sh 79983afe33SPhil Shafer xo --open top/data 80406a584dSPhil Shafer xo --depth 2 '{:tag}' value 81983afe33SPhil Shafer xo --close top/data 82*76afb20cSPhil Shafer 83983afe33SPhil Shafer XML: 84983afe33SPhil Shafer <top> 85983afe33SPhil Shafer <data> 86983afe33SPhil Shafer <tag>value</tag> 87983afe33SPhil Shafer </data> 88983afe33SPhil Shafer </top> 89*76afb20cSPhil Shafer 90983afe33SPhil Shafer JSON: 91983afe33SPhil Shafer "top": { 92983afe33SPhil Shafer "data": { 93983afe33SPhil Shafer "tag": "value" 94983afe33SPhil Shafer } 95983afe33SPhil Shafer } 96983afe33SPhil Shafer 97406a584dSPhil ShaferWhen making partial lines of output (where the format string does not 98406a584dSPhil Shaferinclude a newline), use the `--continuation` option to let secondary 99406a584dSPhil Shaferinvocations know they are adding data to an existing line. 100406a584dSPhil Shafer 101406a584dSPhil ShaferWhen emitting a series of objects, use the `--not-first` option to 102406a584dSPhil Shaferensure that any details from the previous object (e.g. commas in JSON) 103406a584dSPhil Shaferare handled correctly. 104406a584dSPhil Shafer 105406a584dSPhil ShaferUse the `--top-wrap` option to ensure any top-level object details are 106406a584dSPhil Shaferhandled correctly, e.g. wrap the entire output in a top-level set of 107406a584dSPhil Shaferbraces for JSON output. 108406a584dSPhil Shafer 109*76afb20cSPhil Shafer:: 110*76afb20cSPhil Shafer 111*76afb20cSPhil Shafer EXAMPLE: 112406a584dSPhil Shafer #!/bin/sh 113406a584dSPhil Shafer xo --top-wrap --open top/data 114406a584dSPhil Shafer xo --depth 2 'First {:tag} ' value1 115406a584dSPhil Shafer xo --depth 2 --continuation 'and then {:tag}\n' value2 116406a584dSPhil Shafer xo --top-wrap --close top/data 117*76afb20cSPhil Shafer 118406a584dSPhil Shafer TEXT: 119406a584dSPhil Shafer First value1 and then value2 120*76afb20cSPhil Shafer 121406a584dSPhil Shafer HTML: 122406a584dSPhil Shafer <div class="line"> 123406a584dSPhil Shafer <div class="text">First </div> 124406a584dSPhil Shafer <div class="data" data-tag="tag">value1</div> 125406a584dSPhil Shafer <div class="text"> </div> 126406a584dSPhil Shafer <div class="text">and then </div> 127406a584dSPhil Shafer <div class="data" data-tag="tag">value2</div> 128406a584dSPhil Shafer </div> 129*76afb20cSPhil Shafer 130406a584dSPhil Shafer XML: 131406a584dSPhil Shafer <top> 132406a584dSPhil Shafer <data> 133406a584dSPhil Shafer <tag>value1</tag> 134406a584dSPhil Shafer <tag>value2</tag> 135406a584dSPhil Shafer </data> 136406a584dSPhil Shafer </top> 137*76afb20cSPhil Shafer 138406a584dSPhil Shafer JSON: 139406a584dSPhil Shafer { 140406a584dSPhil Shafer "top": { 141406a584dSPhil Shafer "data": { 142406a584dSPhil Shafer "tag": "value1", 143406a584dSPhil Shafer "tag": "value2" 144406a584dSPhil Shafer } 145406a584dSPhil Shafer } 146406a584dSPhil Shafer } 147406a584dSPhil Shafer 148406a584dSPhil ShaferLists and Instances 149406a584dSPhil Shafer------------------- 150406a584dSPhil Shafer 151406a584dSPhil ShaferA "*list*" is set of one or more instances that appear under the same 152406a584dSPhil Shaferparent. The instances contain details about a specific object. One 153406a584dSPhil Shafercan think of instances as objects or records. A call is needed to 154406a584dSPhil Shaferopen and close the list, while a distinct call is needed to open and 155406a584dSPhil Shaferclose each instance of the list. 156406a584dSPhil Shafer 157406a584dSPhil ShaferUse the `--open-list` and `--open-instances` to open lists and 158406a584dSPhil Shaferinstances. Use the `--close-list` and `--close-instances` to close 159406a584dSPhil Shaferthem. Each of these options take a `name` parameter, providing the 160406a584dSPhil Shafername of the list and instance. 161406a584dSPhil Shafer 162406a584dSPhil ShaferIn the following example, a list named "machine" is created with three 163*76afb20cSPhil Shaferinstances:: 164406a584dSPhil Shafer 165406a584dSPhil Shafer opts="--json" 166406a584dSPhil Shafer xo $opts --open-list machine 167406a584dSPhil Shafer NF= 168406a584dSPhil Shafer for name in red green blue; do 169406a584dSPhil Shafer xo $opts --depth 1 $NF --open-instance machine 170406a584dSPhil Shafer xo $opts --depth 2 "Machine {k:name} has {:memory}\n" $name 55 171406a584dSPhil Shafer xo $opts --depth 1 --close-instance machine 172406a584dSPhil Shafer NF=--not-first 173406a584dSPhil Shafer done 174406a584dSPhil Shafer xo $opts $NF --close-list machine 175406a584dSPhil Shafer 176406a584dSPhil ShaferThe normal `libxo` functions use a state machine to help these 177406a584dSPhil Shafertransitions, but since each `xo` command is invoked independent of the 178406a584dSPhil Shaferprevious calls, the state must be passed in explicitly via these 179406a584dSPhil Shafercommand line options. 180406a584dSPhil Shafer 181*76afb20cSPhil ShaferThe `--instance` option can be used to treat a single `xo` invocation 182*76afb20cSPhil Shaferas an instance with the given set of fields:: 183*76afb20cSPhil Shafer 184*76afb20cSPhil Shafer % xo --libxo:XP --instance foo 'The {:product} is {:status}\n' stereo "in route" 185*76afb20cSPhil Shafer <foo> 186*76afb20cSPhil Shafer <product>stereo</product> 187*76afb20cSPhil Shafer <status>in route</status> 188*76afb20cSPhil Shafer </foo> 189*76afb20cSPhil Shafer 190983afe33SPhil ShaferCommand Line Options 191983afe33SPhil Shafer-------------------- 192983afe33SPhil Shafer 193983afe33SPhil Shafer:: 194983afe33SPhil Shafer 195983afe33SPhil Shafer Usage: xo [options] format [fields] 196983afe33SPhil Shafer --close <path> Close tags for the given path 197406a584dSPhil Shafer --close-instance <name> Close an open instance name 198406a584dSPhil Shafer --close-list <name> Close an open list name 199406a584dSPhil Shafer --continuation OR -C Output belongs on same line as previous output 200983afe33SPhil Shafer --depth <num> Set the depth for pretty printing 201983afe33SPhil Shafer --help Display this help text 202983afe33SPhil Shafer --html OR -H Generate HTML output 203*76afb20cSPhil Shafer --instance OR -I <name> Wrap in an instance of the given name 204983afe33SPhil Shafer --json OR -J Generate JSON output 205983afe33SPhil Shafer --leading-xpath <path> Add a prefix to generated XPaths (HTML) 206406a584dSPhil Shafer --not-first Indicate this object is not the first (JSON) 207983afe33SPhil Shafer --open <path> Open tags for the given path 208406a584dSPhil Shafer --open-instance <name> Open an instance given by name 209406a584dSPhil Shafer --open-list <name> Open a list given by name 210406a584dSPhil Shafer --option <opts> -or -O <opts> Give formatting options 211983afe33SPhil Shafer --pretty OR -p Make 'pretty' output (add indent, newlines) 212983afe33SPhil Shafer --style <style> Generate given style (xml, json, text, html) 213983afe33SPhil Shafer --text OR -T Generate text output (the default style) 214406a584dSPhil Shafer --top-wrap Generate a top-level object wrapper (JSON) 215983afe33SPhil Shafer --version Display version information 216983afe33SPhil Shafer --warn OR -W Display warnings in text on stderr 217983afe33SPhil Shafer --warn-xml Display warnings in xml on stdout 218983afe33SPhil Shafer --wrap <path> Wrap output in a set of containers 219983afe33SPhil Shafer --xml OR -X Generate XML output 220*76afb20cSPhil Shafer --xpath Add XPath data to HTML output) 221983afe33SPhil Shafer 222983afe33SPhil ShaferExample 223983afe33SPhil Shafer------- 224983afe33SPhil Shafer 225983afe33SPhil Shafer:: 226983afe33SPhil Shafer 227983afe33SPhil Shafer % xo 'The {:product} is {:status}\n' stereo "in route" 228983afe33SPhil Shafer The stereo is in route 229*76afb20cSPhil Shafer % xo -p -X 'The {:product} is {:status}\n' stereo "in route" 230*76afb20cSPhil Shafer <product>stereo</product> 231*76afb20cSPhil Shafer <status>in route</status> 232*76afb20cSPhil Shafer % xo --libxo xml,pretty 'The {:product} is {:status}\n' stereo "in route" 233983afe33SPhil Shafer <product>stereo</product> 234983afe33SPhil Shafer <status>in route</status> 235