xdoc-rs 0.1.1

Declarative XML engine for Rust
Documentation
# Feature: Schema

Schema permite validar XML con contratos propios del motor. No es XSD completo.
Su objetivo es cubrir validaciones estructurales comunes de forma simple,
tipada y extensible.

## Que aprenderas aqui

[] Declarar rutas requeridas.
[] Validar cardinalidad.
[] Validar tipos simples.
[] Validar valores permitidos.
[] Crear reglas custom.
[] Leer el reporte de validacion.

## Archivo

[] `src/schema/mod.rs`

## Primer contrato

```rust
use xdoc::parser::parse_str;
use xdoc::schema::XmlContract;

let document = parse_str(
    "<Order><ID>O-1</ID><Item>A</Item><Item>B</Item></Order>",
)?;

let report = XmlContract::new("order")
    .required("/Order/ID")?
    .cardinality("/Order/Item", 1, Some(100))?
    .validate(&document)?;

assert!(report.is_valid());
```

## Rutas requeridas

```rust
let contract = XmlContract::new("order")
    .required("/Order/ID")?
    .required("/Order/Customer")?;
```

Si una ruta requerida no produce resultados, el reporte contiene un error.

## Cardinalidad

```rust
let contract = XmlContract::new("order")
    .cardinality("/Order/Item", 1, Some(100))?;
```

Esto significa:

[] Minimo 1 `Item`.
[] Maximo 100 `Item`.

Para maximo abierto:

```rust
let contract = XmlContract::new("order")
    .cardinality("/Order/Item", 1, None)?;
```

## Tipos simples

```rust
use xdoc::schema::{ValueType, XmlContract};

let contract = XmlContract::new("order")
    .text_type("/Order/Total/text()", ValueType::Decimal)?
    .text_type("/Order/Approved/text()", ValueType::Boolean)?;
```

Tipos disponibles:

[] `String`
[] `Integer`
[] `Decimal`
[] `Boolean`

## Enumeraciones

```rust
let contract = XmlContract::new("order")
    .enum_value("/Order/Status/text()", ["draft", "sent", "accepted"])?;
```

Si el valor no esta en la lista, el reporte marca error.

## Namespaces

Schema usa query por debajo, asi que los namespaces se configuran como aliases.

```rust
let contract = XmlContract::new("document")
    .with_namespace("doc", "urn:example:document")?
    .required("/doc:Document/doc:ID")?;
```

## Reglas custom

Usa reglas custom cuando una validacion no cabe en required/cardinality/type.

```rust
use xdoc::schema::{ValidationIssue, XmlContract};

let contract = XmlContract::new("order")
    .rule(|document| {
        let mut issues = Vec::new();

        if document.root().is_none() {
            issues.push(ValidationIssue::error(
                "/",
                "document must have a root element",
            ));
        }

        Ok(issues)
    });
```

## Leer el reporte

```rust
let report = contract.validate(&document)?;

if !report.is_valid() {
    for issue in report.errors() {
        eprintln!("{}: {}", issue.path(), issue.message());
    }
}
```

El reporte separa errores y warnings. Un contrato es valido si no hay issues con
severidad `Error`.

## Cuando usar schema

Usa schema si:

[] Quieres validar XML sin XSD completo.
[] Quieres checks rapidos antes de firmar o transformar.
[] Quieres errores legibles para usuarios.
[] Quieres reglas custom en Rust.

No lo uses si necesitas:

[] XSD completo.
[] Generacion de tipos Rust desde XSD.
[] Validacion normativa de un dominio.

## Errores comunes

[] Esperar que `schema` valide XSD completo.
[] Olvidar aliases de namespace.
[] Usar rutas query no soportadas por el subset.
[] Mezclar reglas de dominio dentro del motor.

## API principal

[] `XmlContract`
[] `ValueType`
[] `ValidationReport`
[] `ValidationIssue`
[] `ValidationSeverity`
[] `ValidationError`
[] `XsdContractAdapter`

## Siguiente lectura

[] [query.md](query.md) para entender las rutas.
[] [transform.md](transform.md) para convertir XML validado.
[] [cli.md](cli.md) para validar desde terminal con contratos simples.

[Volver al indice](features.md).