# declxml
## declxml
`declxml` is a Rust crate that lets you **declare XML trees at compile time**
with macros and provides deserializers with derive macros.
Namespaces, attributes, and element names are checked during macro expansion.
### Features
- **`xml!` macro** for inline XML AST construction.
- **Pre-sorted attributes and namespaces** for Exclusive C14N serialization.
- **Pre-escaped literal values** for safe XML output.
- Produces a lightweight AST (`Element`, `Attr`, etc.) that can be serialized
directly without runtime sorting.
### Assumptions
- **Tag names** are known at compile time.
- **Namespaces** and their URIs are known at compile time.
- **Attribute names** are known at compile time, while their values can be dynamic.
#### Strict Namespace Model
`declxml` enforces a **strict namespace model** to simplify canonicalization:
- Elements and attributes may be either:
- **Un-namespaced**: no prefix, no associated namespace, or
- **Prefixed**: a declared prefix must always be used (e.g. `example:root`).
- The XML default namespace form (`<Element xmlns="…">`) is **not allowed**.
If you want to use a namespace, declare it in the `@ns` block and use the
prefix consistently (`example:Element`).
### Example
```rust
use declxml::xml;
let doc = xml! {
// Namespace Declarations
// Namespaces are declared once, before the root element:
// Undeclared / unused prefix causes a compile-time error.
@ns {
example = "uri:ns",
other = "uri:other",
}
// All documents must start with exactly one root element:
example:root {
// children here
// Empty elements
// Use a trailing semicolon (;) as shorthand for no children
nochildren;
// Attributes
// Declared after the element name, before children.
// Attributes may have prefixes or not
example:withattrs other:id="my_id" {
subchild other:id="other_id";
}
// Dynamic values
// Wrap a Rust expression in parentheses `(…)` to inject it at runtime.
//
// • In attributes: the expression must be "string-like" such as
// `&str`, `String`, `Box<str>`, etc.
// • In children: the expression must be either
// - another XML element (from `xml!`), or
// - any "string-like" type (e.g. `&str`, `String`, `Box<str>`, etc.).
(custom_child)
// Attribute with dynamic value
custom_attr my_attr=(attr_value);
}
};
```