PureXML/README.md
Mihaela Mihaljevic 0f3086c8e6 docs(roadmap): add Apple-palette mermaid roadmap and the roadmap gate
Follow the mihaela-agents mermaid rule: add a README roadmap using the TileDown
Apple-color status classes (done/review/epic/todo), legend block first, then a
libxml2-parity roadmap showing shipped vs open work. Add docs/rules/mermaid.md
and scripts/check-roadmap.sh (wired into check-all.sh) so the diagrams stay
mechanically checkable.
2026-06-08 00:58:50 +02:00

156 lines
5.4 KiB
Markdown

# PureXML
[![macOS CI](https://img.shields.io/github/actions/workflow/status/mihaelamj/PureXML/ci.yml?branch=main&label=macOS)](https://github.com/mihaelamj/PureXML/actions/workflows/ci.yml)
[![Linux CI](https://img.shields.io/github/actions/workflow/status/mihaelamj/PureXML/ci.yml?branch=main&label=Linux)](https://github.com/mihaelamj/PureXML/actions/workflows/ci.yml)
[![WASI CI](https://img.shields.io/github/actions/workflow/status/mihaelamj/PureXML/ci.yml?branch=main&label=WASI)](https://github.com/mihaelamj/PureXML/actions/workflows/ci.yml)
PureXML is a dependency-free XML package written entirely in Swift.
The goal is a Linux-, Windows-, and WebAssembly-compatible XML reader/writer that
does not pull in `libxml2`, `expat`, or Foundation's `XMLParser`. The package is
intentionally strict about portability:
- no external SwiftPM dependencies
- no bundled C sources
- no Foundation requirement in the library target
- root Swift package layout
- macOS, Linux, Windows, and WASI build gates
It is a sibling project to [PureYAML](https://github.com/mihaelamj/PureYAML) and
follows the same structure, rules, and verification gates.
## Roadmap
The roadmap uses the TileDown Mermaid palette: green for shipped work, yellow for
review, purple for epic grouping, and gray for open work.
```mermaid
flowchart TB
classDef done fill:#ddf9e4,stroke:#34c759,color:#111827
classDef review fill:#fff7d6,stroke:#ffcc00,color:#111827
classDef epic fill:#f2e5ff,stroke:#af52de,color:#111827
classDef todo fill:#f2f4f7,stroke:#8e8e93,color:#111827
LDone["In main now"]:::done
LReview["PR in review"]:::review
LEpic["Epic grouping"]:::epic
LTodo["Open issue, no PR"]:::todo
LDone --> LReview
LReview --> LEpic
LEpic --> LTodo
```
Capability is being grown toward libxml2 parity in pure Swift, guided by the
private PureXML-research analysis. Shipped vs open work:
```mermaid
flowchart TB
classDef done fill:#ddf9e4,stroke:#34c759,color:#111827
classDef review fill:#fff7d6,stroke:#ffcc00,color:#111827
classDef epic fill:#f2e5ff,stroke:#af52de,color:#111827
classDef todo fill:#f2f4f7,stroke:#8e8e93,color:#111827
Model["Node model + emitter"]:::done
Stream["Streaming pull parser"]:::done
Escape["Iterative emitter + escaping"]:::done
Limits["Bounded-by-default limits"]:::done
Bytes["Byte input + encoding detection"]:::done
Namespaces["Namespace resolution"]:::todo
ByteStream["Streaming byte decode"]:::todo
DTD["Optional DTD + entities"]:::todo
Validation["Schema validation"]:::todo
XPath["XPath 1.0"]:::todo
Model --> Stream
Stream --> Escape
Escape --> Limits
Limits --> Bytes
Bytes --> Namespaces
Namespaces --> ByteStream
ByteStream --> DTD
DTD --> Validation
Validation --> XPath
```
## Status
The node model, the emitter, and a streaming parser are implemented and usable
today.
- **Model** (`PureXML.Model`): `Node`, `Element`, `Attribute`, `QualifiedName`.
Preserves document order and the distinction between text, CDATA, comments,
and processing instructions.
- **Emitting** (`PureXML.Emitting`): `Serializer` turns a node tree into
well-formed XML, with pretty-printed and compact options and correct text and
attribute escaping.
- **Validation** (`PureXML.Validation`): structural checks such as duplicate
attribute names. Schema validation (DTD/XSD/RELAX NG) is out of scope for the
library target.
- **Parsing** (`PureXML.Parsing`): a streaming, iterative parser. `EventReader`
is a pull-based event core that consumes input through a character-source
closure and emits one `Event` at a time, never holding the whole document in
memory (it drives chunked input). `Parser` builds a `Model.Node` tree
iteratively over the event core. Handles elements, attributes, text, the five
predefined entities and numeric character references, comments, CDATA, and
processing instructions. Safe by default: `<!DOCTYPE>` is rejected, which
removes the DTD-based threat classes (XXE, entity-expansion DoS). DTD support,
namespaces-as-resolved-URIs, and validation are deliberate future layers.
## Usage
```swift
import PureXML
// Build a tree and emit it (works today).
let element = PureXML.Model.Element(
"book",
attributes: [.init("id", "bk101")],
children: [.element(.init("title", children: [.text("XML Developer's Guide")]))],
)
let xml = PureXML.serialize(.element(element))
try PureXML.validate(.element(element))
// Parse it back into a tree.
let node = try PureXML.parse(xml)
// Or stream events without building a tree (drives chunked input too).
var reader = PureXML.events(xml)
while let event = try reader.next() {
// handle .startElement / .characters / .endElement / ...
}
```
## Attribution
PureXML is informed by the behavior of established XML parsers (`libxml2`,
`expat`, Foundation's `XMLParser`) and by the W3C XML 1.0 specification, but it
does not copy their implementation into `Sources/`. See
[ATTRIBUTION.md](ATTRIBUTION.md).
## Development Contract
PureXML must stay dependency-free and portable. Before merging changes:
- Swift tools version: 6.1
- Package products: `PureXML`
- SwiftPM dependencies: none
- Hosted CI matrix: macOS, Linux, Windows, and WASM
```sh
bash scripts/check-all.sh
```
That command expands to:
```sh
bash scripts/check-style.sh
bash scripts/check-namespacing.sh
bash scripts/check-forbidden-patterns.sh
swiftformat . --config .swiftformat --lint
swiftlint --config .swiftlint.yml --strict
swift build
swift test
```
## License
MIT.