# Feature: Writer
Writer convierte un `Document` en un string XML. Es la ultima etapa normal del
flujo: construyes o parseas un documento, opcionalmente consultas/validas/firma,
y luego serializas.
## Que aprenderas aqui
- [ ] Serializar compacto o pretty.
- [ ] Controlar la declaracion XML.
- [ ] Entender como se escapan texto y atributos.
- [ ] Saber cuando pretty puede cambiar la apariencia del XML.
- [ ] Usar writer con parser, macro y firma.
## Archivo
- [ ] `src/writer/mod.rs`
## Serializacion compacta
```rust
use xdoc::macros::xml;
use xdoc::writer::to_string_compact;
let document = xml! {
<Root>
<Item code="A">one</Item>
</Root>
}?
.into_document()?;
let output = to_string_compact(&document)?;
assert_eq!(output, "<Root><Item code=\"A\">one</Item></Root>");
```
La salida compacta es util para:
- [ ] Comparaciones exactas.
- [ ] Goldens.
- [ ] Canonicalizacion previa a algunas operaciones.
- [ ] Logs donde no importa la legibilidad.
## Serializacion pretty
```rust
use xdoc::writer::{to_string_pretty, WriterConfig};
let output = to_string_pretty(
&document,
WriterConfig::pretty().with_xml_declaration(false),
)?;
```
Salida:
```xml
<Root>
<Item code="A">one</Item>
</Root>
```
## Declaracion XML
```rust
let output = to_string_pretty(
&document,
WriterConfig::pretty()
.with_xml_declaration(true)
.with_encoding("UTF-8"),
)?;
```
La declaracion queda al inicio:
```xml
<?xml version="1.0" encoding="UTF-8"?>
```
## Indentacion
```rust
let config = WriterConfig::pretty()
.with_xml_declaration(false)
.with_indent(" ");
```
El indent default pretty es de dos espacios.
## Escape de texto y atributos
Writer escapa caracteres especiales automaticamente.
```rust
let document = xml! {
<Message text={ "A & B" }>
{ "2 < 3" }
</Message>
}?
.into_document()?;
let output = to_string_compact(&document)?;
```
Salida:
```xml
<Message text="A & B">2 < 3</Message>
```
No insertes XML raw como string esperando que se interprete como nodos. Si
interpolas `"<Child/>"` como texto, se serializa escapado.
## Mixed content
Pretty evita reindentar agresivamente cuando hay contenido mixto:
```xml
<p>Hello <b>world</b>!</p>
```
En XML con mixed content, agregar saltos o espacios puede cambiar el significado
del texto. Por eso writer preserva ese contenido con mas cuidado que un pretty
printer generico.
## Writer y firma
Para firma, la representacion importante no es el pretty output sino la
canonicalizacion. Aun asi, writer debe producir XML estructuralmente estable.
Buenas practicas:
- [ ] Construir el documento completo antes de firmar.
- [ ] No modificar nodos firmados despues de firmar.
- [ ] Usar canonicalizacion de `signature` para digest y `SignatureValue`.
- [ ] Usar writer solo para producir el XML final.
## Errores comunes
- [ ] Comparar pretty output cuando el XML tiene mixed content sensible.
- [ ] Esperar que writer valide XSD.
- [ ] Esperar que writer resuelva namespaces no declarados.
- [ ] Insertar XML raw como texto.
## API principal
- [ ] `WriterConfig`
- [ ] `to_string_compact`
- [ ] `to_string_pretty`
- [ ] `to_string_with_config`
- [ ] `escape_text`
- [ ] `escape_attribute`
## Siguiente lectura
- [ ] [parser.md](parser.md) para leer XML externo.
- [ ] [testing.md](testing.md) para golden tests.
- [ ] [signature.md](signature.md) para canonicalizacion.
[Volver al indice](features.md).