XML Activities
Versión: 1.1.0 · ID: zoan-packages-xml · Autor: Zoan Software
El paquete XML lee, consulta y modifica documentos XML, un formato de intercambio de datos muy usado en integraciones (facturación electrónica, servicios web SOAP, configuraciones, reportes que exportan otros sistemas). Te permite extraer datos de un XML y modificarlo sin tener que parsear el texto a mano.
Cómo funciona este paquete
Sección titulada «Cómo funciona este paquete»Las actividades trabajan sobre el texto XML (una cadena), no sobre un archivo abierto. El patrón típico es:
- Read XML lee el archivo y devuelve su contenido como string.
- Consultas valores con XML Query Text / XML Query All, conviertes todo a un diccionario con XML to Dictionary, o lo modificas con XML Set Value / XML Add Element (que devuelven el XML modificado).
- Write XML guarda el resultado a un archivo.
Read XML path = ruta → output: xmlXML Query Text xml = xml xpath = "//Factura/Total" → output: totalLas actividades que modifican (XML Set Value, XML Add Element) devuelven el documento con sangría y sin la declaración <?xml …?>. Write XML vuelve a escribir la declaración, con la codificación del archivo, al guardarlo.
XPath en una cucharada
Sección titulada «XPath en una cucharada»| XPath | Selecciona |
|---|---|
//Numero | Todos los elementos <Numero> en cualquier nivel |
//Factura/Numero | Los <Numero> hijos directos de <Factura> |
//Factura[@id='5'] | La <Factura> con atributo id="5" |
//Item[2] | El segundo <Item> |
//Total/@moneda | El valor del atributo moneda de <Total> |
count(//Item) | Cuántos <Item> hay |
El XPath (1.0) se evalúa sobre el documento completo. Puede seleccionar elementos, atributos, nodos de texto o calcular un valor (count(…), sum(…), una comparación); las actividades de consulta devuelven siempre su texto:
- Un elemento con hijos devuelve el texto de todos sus descendientes, unido.
- Un número entero sale sin decimales (
3, no3.0); un booleano, comotrueofalse.
Namespaces
Sección titulada «Namespaces»Muchos XML de integraciones (facturas UBL, SOAP) usan namespaces: los nombres llevan un prefijo, como cbc:ID o cac:InvoiceLine, declarado con xmlns:cbc="…". Desde la versión 1.1.0, las actividades con xpath los registran solas:
- Los prefijos declarados en el documento (en la raíz o más adentro) se usan tal cual en el XPath:
//cbc:ID,//cac:LegalMonetaryTotal/cbc:PayableAmount. No hace faltalocal-name(). - El namespace por defecto (
xmlns="…", sin prefijo) se escribe en el XPath con el prefijod:—/d:Invoice/cbc:ID. Puedes cambiarlo condefaultPrefix(vacío equivale ad). Si el documento ya declara un prefijodpara otro namespace, ese manda: elige otrodefaultPrefix(p. ej.n) para llegar al namespace por defecto. - Si el XPath no encuentra nada, el documento tiene namespace por defecto y el XPath no usa su prefijo, el log te lo recuerda con un aviso: El XML tiene un namespace por defecto: en el XPath escribe sus elementos con el prefijo ‘d:’ (p. ej. //d:Invoice).
- Con el parámetro opcional
namespaces(diccionario prefijo → URI) agregas prefijos propios o reemplazas los del documento; los tuyos mandan. - Si el XPath usa un prefijo que no existe, el error dice cuál y qué prefijos hay.
- Si un mismo prefijo se declara con dos URI distintas, vale la primera en el orden del documento; para usar la otra, defínela en
namespaces.
XML Query Text xml = documento xpath = "//inv:Total" namespaces = dictSet(newDict(), "inv", "urn:ejemplo:facturas") → output: totalXML dentro de XML (factura electrónica)
Sección titulada «XML dentro de XML (factura electrónica)»A veces un XML trae otro XML como texto, dentro de un CDATA. Es el caso de la factura electrónica de Colombia (DIAN, UBL 2.1): llega como un AttachedDocument y la factura real va en cac:Attachment/cac:ExternalReference/cbc:Description. Se resuelve en dos pasos: extraer ese texto y consultarlo directamente (no hace falta guardarlo en un archivo).
Read XML path = ruta → output: contenedorXML Query Text xml = contenedor xpath = "//cac:Attachment/cac:ExternalReference/cbc:Description" → output: facturaXML Query Text xml = factura xpath = "/d:Invoice/cbc:ID" → output: numeroXML Query Text xml = factura xpath = "//cac:AccountingSupplierParty/cac:Party/cac:PartyTaxScheme/cbc:CompanyID" → output: nitEmisorXML Query Text xml = factura xpath = "/d:Invoice/cbc:IssueDate" → output: fechaXML Query Text xml = factura xpath = "/d:Invoice/cbc:DueDate" → output: vencimientoXML Query Text xml = factura xpath = "//cac:LegalMonetaryTotal/cbc:PayableAmount" → output: totalXML Query Text xml = factura xpath = "/d:Invoice/cbc:UUID" → output: cufeXML Query All xml = factura xpath = "//cac:InvoiceLine/cbc:LineExtensionAmount" → output: valoresLineasSi necesitas muchos datos, convierte la factura una sola vez con XML to Dictionary. El texto que sale del CDATA puede empezar con saltos de línea, espacios o un BOM antes de <?xml …?>: las actividades los ignoran. También sirve si el XML embebido viene escapado (<Invoice…) en lugar de en un CDATA.
Seguridad y límites
Sección titulada «Seguridad y límites»Desde la versión 1.1.0, todas las actividades leen el XML de forma segura (también Read XML y Write XML, que validan el documento):
- No se admiten DTD (
<!DOCTYPE …>) ni entidades: un XML con DTD se rechaza con un error claro. Así se evitan los ataques de entidades externas (XXE), que intentan leer archivos del equipo, y las «bombas» de expansión de entidades. - Tamaño máximo: 50 MB por documento (50 M caracteres si llega como texto).
- Anidamiento máximo: 256 niveles.
Errores comunes del paquete
Sección titulada «Errores comunes del paquete»Estos mensajes pueden salir de cualquier actividad que lea XML y detienen la actividad. Si el XML viene de fuera y puede llegar dañado, envuelve la lectura en Try Catch.
| Mensaje | Causa y solución |
|---|---|
| Mensaje del analizador XML con línea y posición (p. ej. Data at the root level is invalid. Line 1, position 1.) | El texto no es un XML bien formado: etiquetas sin cerrar, texto antes de la raíz, & sin escapar. Revisa el origen del texto. |
El XML declara una DTD (<!DOCTYPE>). Por seguridad (XXE) no se admiten DTD ni entidades; quita la declaración <!DOCTYPE>. | El documento trae <!DOCTYPE …>. Pide el archivo sin DTD o quítala del texto antes de procesarlo. |
El XML es demasiado grande (… MB); el límite es 50 MB. | El documento supera el tope. Pide archivos más pequeños o divídelos en origen. |
El XML tiene más de 256 niveles de anidamiento. | Estructura anormalmente profunda. |
La expresión XPath «…» no es válida: … | Error de sintaxis en el XPath (corchetes o comillas sin cerrar, función inexistente). |
El prefijo 'x:' no está declarado en el XML ni en 'namespaces'. Prefijos disponibles: …. | El XPath usa un prefijo que el documento no declara. Usa uno de la lista o defínelo en namespaces. |
'namespaces' debe ser un diccionario de prefijo → URI del namespace. | Pasaste un texto o una lista en namespaces. Usa un diccionario. |
'…' no es un prefijo de namespace válido en 'namespaces'. / El prefijo '…' de 'namespaces' no tiene URI de namespace. | Una clave de namespaces no es un nombre XML válido (o es xml/xmlns), o su URI está vacía. |
'…' no es un prefijo válido para el namespace por defecto. | defaultPrefix no es un nombre XML válido (sin espacios ni :), o es xml/xmlns. |
Actividades
Sección titulada «Actividades»| Actividad | Tipo | Salida | Qué hace |
|---|---|---|---|
| Read XML | xml-read | string | Lee un archivo XML como texto |
| Write XML | xml-write | string | Guarda un texto XML a un archivo |
| XML Query Text | xml-query-text | string | Primer valor que coincide con un XPath |
| XML Query All | xml-query-all | List | Todos los valores que coinciden |
| XML to Dictionary | xml-to-dictionary | Dictionary | Convierte el XML (o un fragmento) en un diccionario navegable |
| XML Set Value | xml-set-value | string | Cambia el valor de un elemento o atributo |
| XML Add Element | xml-add-element | string | Agrega un elemento hijo |
Siguientes pasos
Sección titulada «Siguientes pasos»- Read XML — leer un archivo XML.
- XML Query Text — extraer un dato con XPath.
- XML to Dictionary — todos los datos de una vez.
- JSON — para datos en formato JSON.