# CLI Reference

> Complete reference for the `xml-validate` and `xml-format` command-line tools.
> **v1.7.0**

---

## Installation

```bash
npm install -g xml-xsd-engine     # global install
npm install xml-xsd-engine        # local install (use via npx or package scripts)
```

---

## xml-validate

### Synopsis

```
xml-validate [options] <xml-files...> [schema.xsd]
```

### Options

| Flag | Description                                                           |
|------|-----------------------------------------------------------------------|
| `--format <format>` | Output format: `text` (default), `compact`, `json`, `github`, `junit` |
| `--well-formed` | Check well-formedness only (no schema required)                       |
| `--lax` | Lax validation (unknown elements/attributes are warnings, not errors) |
| `--recover` | Continue after structural errors to collect all issues                |
| `--watch` | Re-validate when files change (200ms debounce, concurrent-run guard)  |
| `--code-frame` | Show source context around errors                                     |
| `--fail-fast` | Stop after first error                                                |
| `--silent` | No output — exit code only                                            |
| `--no-color` | Disable ANSI color output                                             |
| `--streaming` | Use SAX-based streaming validator (no DOM; v1.7)                      |
| `--psvi` | Emit PSVI type annotations after validation (DOM mode only)           |

### Exit Codes

| Code | Meaning |
|------|---------|
| `0` | Valid (or well-formed if no schema provided) |
| `1` | Validation errors found |
| `2` | Parse error (document not well-formed) |
| `3` | File not found or read error |

### Examples

```bash
# Basic validation
xml-validate order.xml order.xsd

# Multiple files with glob
xml-validate data/*.xml schema.xsd

# Well-formedness only
xml-validate --well-formed *.xml

# Streaming mode (v1.7 — no DOM allocation)
xml-validate --streaming large-document.xml schema.xsd

# JSON output for CI tools
xml-validate data.xml schema.xsd --format json

# JUnit XML for test runners
xml-validate data.xml schema.xsd --format junit > results.xml

# GitHub Actions annotations
xml-validate data.xml schema.xsd --format github

# Watch mode (200ms debounce, safe concurrent restart)
xml-validate --watch data.xml schema.xsd

# Show code frame around errors
xml-validate data.xml schema.xsd --code-frame

# Lax mode (allow unknown elements as warnings)
xml-validate data.xml schema.xsd --lax

# Recover (collect all errors without stopping at first)
xml-validate data.xml schema.xsd --recover

# Silent (just exit code)
xml-validate data.xml schema.xsd --silent && echo "valid" || echo "invalid"

# PSVI type annotations (DOM mode only)
xml-validate data.xml schema.xsd --psvi --format json
```

### Output Formats

**text** (default):
```
VALID: data.xml
  2 warnings

WARNING  /catalog/book[1]  @12:5  Element 'isbn' is optional but absent
```

**compact**:
```
data.xml:12:5: WARNING [VALIDATION_MISSING_ELEMENT] /catalog/book[1] Element 'isbn' is optional but absent
```

**json**:
```json
{
  "file": "data.xml",
  "valid": true,
  "errors": 0,
  "warnings": 1,
  "issues": [
    { "severity": "warning", "path": "/catalog/book[1]", "line": 12, "col": 5,
      "code": "VALIDATION_MISSING_ELEMENT", "message": "Element 'isbn' is optional but absent" }
  ]
}
```

**github**:
```
::warning file=data.xml,line=12,col=5,title=VALIDATION_MISSING_ELEMENT::/catalog/book[1] Element 'isbn' is optional but absent
```

**junit**:
```xml
<testsuite name="xml-validate" tests="1" errors="0" failures="1">
  <testcase name="data.xml">
    <failure type="VALIDATION_MISSING_ELEMENT" message="..."/>
  </testcase>
</testsuite>
```

### Streaming Mode (`--streaming`)

> Added in v1.7

When `--streaming` is passed, `xml-validate` uses `validateStreaming()` (SAX-driven) instead of the DOM-based `validate()`. Benefits:

- **No DOM allocation** — constant memory regardless of document depth
- **Faster time-to-first-error** — issues emitted as parsing progresses
- **Large files** — suitable for documents too large to hold in memory

Limitations:
- PSVI annotations not available (`--psvi` ignored in streaming mode)
- XPath-based `xs:assert` not evaluated
- Identity constraints evaluated within document scope only (full keyref supported via `StreamingKeyrefTracker`)

---

## xml-format

### Synopsis

```
xml-format [options] <xml-file>
```

### Options

| Flag | Description |
|------|-------------|
| `--indent <n>` | Spaces per indent level (default: 2) |
| `--declaration` | Prepend `<?xml version="1.0"?>` |
| `--in-place` | Overwrite input file |
| `--output <file>` | Write to specified output file |
| `--canonical` | Output in W3C Canonical XML 1.0 form (v1.7) |

### Examples

```bash
# Pretty-print to stdout
xml-format data.xml

# Custom indent
xml-format data.xml --indent 4

# Add XML declaration
xml-format data.xml --declaration

# Canonical XML output (v1.7)
xml-format data.xml --canonical

# Overwrite in place
xml-format data.xml --in-place

# Write to file
xml-format data.xml --output formatted.xml
```

### Notes

- Mixed-content elements (text + child elements) are not re-indented to avoid changing semantics
- Self-closing tags are preserved (`<empty/>`) except in `--canonical` mode (expanded to `<empty></empty>`)
- CDATA sections are preserved as-is unless `--canonical` mode is used (expanded to text)
- `--canonical` mode: attributes sorted, namespace declarations sorted, XML declaration stripped
