# Feature: Query
Query permite consultar nodos, atributos y textos dentro de un `Document`. Es un
subset tipo XPath, pensado para casos comunes del motor. No es XQuery ni XPath
completo.
## Que aprenderas aqui
- Consultar rutas absolutas.
- Buscar descendientes.
- Leer atributos y textos.
- Usar predicados simples.
- Consultar XML con namespaces.
- Entender que query no modifica el documento.
## Archivo
- `src/query/mod.rs`
## Primer query
```rust
use xdoc::parser::parse_str;
use xdoc::query::DocumentQueryExt;
let document = parse_str("<Root><Item code=\"A\">one</Item></Root>")?;
let result = document.query("/Root/Item/text()")?;
assert_eq!(result.strings(), vec!["one"]);
```
## Rutas absolutas
```rust
let items = document.query("/Root/Items/Item")?;
let node_ids = items.nodes();
```
Una ruta absoluta empieza desde el root del documento.
## Descendientes
```rust
let all_items = document.query("//Item")?;
```
`//Item` busca elementos `Item` en cualquier nivel.
## Atributos
```rust
let codes = document.query("/Root/Item/@code")?;
let values = codes.strings();
```
Los atributos se devuelven como `QueryValue::Attribute`, y `strings()` retorna
sus valores.
## Texto
```rust
let text = document.query("/Root/Item/text()")?.strings();
```
`text()` selecciona nodos texto hijos directos del elemento seleccionado.
## Predicados simples
```rust
let selected = document.query("/Root/Item[@code='A']/text()")?;
assert_eq!(selected.strings(), vec!["one"]);
```
El MVP soporta predicados simples de igualdad por atributo.
## Namespaces
Query usa aliases explicitos.
```rust
use xdoc::query::{DocumentQueryExt, NamespaceContext};
let namespaces = NamespaceContext::new()
.with_alias("doc", "urn:example:document")?;
let result = document.query_with_context(
"/doc:Document/doc:Item/text()",
&namespaces,
)?;
```
Aunque el XML tenga namespace default, en query usa alias explicito para evitar
ambiguedades.
## Reutilizar queries
```rust
use xdoc::query::Query;
let query = Query::parse("//Item[@code='A']")?;
let first = query.evaluate(&document)?;
let second = query.evaluate(&other_document)?;
```
Esto es util si vas a evaluar la misma expresion muchas veces.
## Que retorna QueryResult
`QueryResult` puede contener:
- `QueryValue::Node(NodeId)`
- `QueryValue::Text(String)`
- `QueryValue::Attribute { name, value }`
Helpers:
- `values()`: acceso completo.
- `nodes()`: solo nodos.
- `strings()`: textos y valores de atributos.
- `len()`.
- `is_empty()`.
## Errores comunes
- Esperar XPath completo.
- Usar namespace default sin alias.
- Intentar modificar XML desde query.
- Usar comillas no soportadas en predicados complejos.
- Esperar funciones XPath arbitrarias.
## API principal
- `Query`
- `QueryResult`
- `QueryValue`
- `NamespaceContext`
- `DocumentQueryExt`
## Siguiente lectura
- [schema.md](schema.md) porque los contratos usan query.
- [transform.md](transform.md) porque los templates pueden seleccionar datos.
- [signature.md](signature.md) porque placement de firma puede usar query.
[Volver al indice](features.md).