declxml-macros 0.1.0

`declxml-macros` Used By `declxml` Crate
Documentation
# 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);
    }
};
```