Trabajo con XML en Swift (iOS/macOS)
XML (Extensible Markup Language) sigue siendo un formato demandado para el intercambio de datos, archivos de configuración y almacenamiento de información estructurada. En el ecosistema de Apple (iOS, macOS, watchOS, tvOS) las herramientas integradas de Foundation proporcionan dos enfoques principales para trabajar con XML: análisis por flujo (similar a SAX) con XMLParser y enfoque de árbol DOM a través de XMLDocument (disponible en macOS). En este artículo analizaremos ambos métodos en detalle, proporcionaremos ejemplos prácticos y consideraremos escenarios de uso típicos.
1. Análisis por flujo con XMLParser
XMLParser es un analizador orientado a eventos que forma parte de Foundation. No carga todo el XML en memoria, sino que analiza el documento secuencialmente, llamando a métodos del delegado al detectar elementos, atributos, texto, etc. Es la solución ideal para archivos grandes o datos en flujo.
Ejemplo básico de análisis de un feed RSS
import Foundation
// 1. Creamos la clase delegadaclass RSSParserDelegate: NSObject, XMLParserDelegate { var currentElement = "" var currentTitle = "" var currentLink = "" var items: [(title: String, link: String)] = [] // Se llama al abrir una etiqueta func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) { currentElement = elementName if elementName == "item" { currentTitle = "" currentLink = "" } } // Se llama al encontrar contenido de texto func parser(_ parser: XMLParser, foundCharacters string: String) { switch currentElement { case "title": currentTitle += string case "link": currentLink += string default: break } } // Se llama al cerrar una etiqueta func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { if elementName == "item" { items.append((title: currentTitle.trimmingCharacters(in: .whitespacesAndNewlines), link: currentLink.trimmingCharacters(in: .whitespacesAndNewlines))) } }}
// 2. Usolet xmlString = """<rss> <channel> <item> <title>Swift 5.9 Features</title> <link>https://example.com/swift-5-9</link> </item> </channel></rss>"""
guard let data = xmlString.data(using: .utf8) else { fatalError() }let parser = XMLParser(data: data)let delegate = RSSParserDelegate()parser.delegate = delegate
if parser.parse() { for item in delegate.items { print("Title: \\(item.title), Link: \\(item.link)") }} else { print("Error de análisis: \\(parser.parserError?.localizedDescription ?? "desconocido")")}2. Modelo de árbol: XMLDocument (solo macOS)
En macOS (y en aplicaciones que usan Swift Package Manager con el framework Foundation en modo macOS) está disponible la clase XMLDocument, que hereda de XMLNode. Permite cargar todo el XML en memoria y manipularlo como un árbol. Es conveniente para documentos pequeños cuando se necesita acceso aleatorio a los nodos.
Creación y modificación de un documento XML
import Foundation
// Creamos el elemento raízlet rootElement = XMLElement(name: "catalog")let document = XMLDocument(rootElement: rootElement)
// Añadimos un elemento hijo con un atributolet book = XMLElement(name: "book")book.addAttribute(XMLNode.attribute(withName: "id", stringValue: "101") as! XMLNode)let title = XMLElement(name: "title", stringValue: "Swift Programming")let author = XMLElement(name: "author", stringValu También en la biblioteca
parking_lot Rust: guía completa con ejemplos prácticos
Generación de PDF en PHP: bibliotecas, herramientas y ejemplos de código
Registro en Go: Resumen de la biblioteca estándar log y alternativas