CLI
Invocation modes, options, and the REPL.
Options
xsql - SQL-like language for querying and mutating XML files
Usage:
xsql interactive mode (REPL)
xsql <script.xsql> run a script file
xsql -e "<query>" run an inline query
<producer> | xsql read the script from stdin
<xml> | xsql script.xsql pipe an XML document to `USE INPUT`
Options:
-e, --eval <QUERY> inline query
-i, --interactive force interactive mode even with piped stdin
-h, --help show this help
-V, --version show versionA script file and -e are mutually exclusive. -e and a script file
argument can't both be given.
Output
Output always goes to stdout:
SELECTresults print immediately, in script order.- Every document a script actually modified is serialized (pretty-printed) once the whole script finishes.
Errors go to stderr with file:line:col diagnostics, and the process
exits non-zero.
USE INPUT: filter mode
USE INPUT selects the XML document piped in on stdin, instead of a file on
disk — this is what makes xsql a proper Unix filter:
cat db.xml | xsql -e "USE INPUT UPDATE goods SET cost = cost * 2;" > db.xmlIf a script uses USE INPUT but the script itself didn't come from stdin
(e.g. it was a file or -e query), xsql reads the XML document from stdin
separately.
REPL
Running xsql with no arguments and nothing piped in starts an interactive
session, like node or python:
xsql 0.1.0 — interactive mode
End statements with `;`. Commands: .help .dump BEGIN COMMIT ROLLBACK [TO name] CHECKPOINT name (alias SAVEPOINT) exit
xsql> USE db.xml
...> SELECT GROUP goods;- A statement runs once it lexes cleanly and its last token is the
;terminator — unterminated strings orRAW XMLblocks keep the continuation prompt (...>) open for multi-line input. USEand any in-memory edits persist across statements in the same session..dumppreviews every document modified so far — printed to stdout, never touches disk, doesn't affect transaction state below..helpshows the REPL command reference.exit/quit/.exit(or EOF, Ctrl+D / Ctrl+Z) leaves the REPL — emitting any pending edits to stdout on the way out (soxsql > out.xmlstill captures them), and printing a warning to stderr if they were neverCOMMITted to disk.
Transactions
The REPL is always implicitly "inside a transaction" per loaded document —
mutating statements only ever change the in-memory copy, exactly as before.
COMMIT is the only thing that writes to disk. Both a bare SQL-style
spelling and a dot-prefixed spelling work for every command below (COMMIT
or .commit, etc.):
COMMIT— writes every modified document back to its original file path. A document loaded viaUSE INPUThas no file to write to, so it's printed to stdout instead (same as.dump).ROLLBACK— discards every uncommitted edit, restoring each document to its state as of the lastCOMMIT(or when it was first loaded).CHECKPOINT <name>(aliasSAVEPOINT <name>) — snapshots every loaded document under a name, without committing anything.ROLLBACK TO <name>— restores every document to its<name>snapshot, discarding any later checkpoints but keeping<name>itself (so you can roll back to it again). Errors if no document has that checkpoint.BEGIN— clears all checkpoints (a "fresh start" marker). Since the session is always implicitly in a transaction,BEGINdoesn't change what a bareROLLBACKrestores to — onlyCOMMIT/ROLLBACKdo that.
xsql> USE db.xml
...> UPDATE goods SET cost = cost * 2;
xsql> CHECKPOINT before_tax;
xsql> UPDATE goods SET cost = cost + 1;
xsql> ROLLBACK TO before_tax;
xsql> COMMIT;
committed -> db.xmlTransactions and COMMIT are REPL-only; one-shot script/-e/stdin-script
runs always write their output to stdout, as described above.
Diagnostics
SET ANALYZE = ON (or the ANALYZE; shorthand) prints a per-stage timing
report to stderr after the run: lex, parse, stdin/file read, XML parse per
document, per-block execution, serialization, output assembly, stdout
write, total DOM memory, and total time. See Settings.