Analizar un archivo XML con SAX Parser

1. Información general

SAX, también conocido como API simple para XML , se utiliza para analizar documentos XML.

En este tutorial, aprenderemos qué es SAX y por qué, cuándo y cómo debe usarse.

2. SAX : la API simple para XML

SAX es una API que se utiliza para analizar documentos XML. Se basa en eventos generados durante la lectura del documento. Los métodos de devolución de llamada reciben esos eventos. Un controlador personalizado contiene esos métodos de devolución de llamada.

La API es eficiente porque descarta eventos justo después de que las devoluciones de llamada los recibieron. Por lo tanto, SAX tiene una gestión de memoria eficiente , a diferencia de DOM, por ejemplo.

3. SAXO vs DOM

DOM son las siglas de Document Object Model. El analizador DOM no se basa en eventos . Además, carga todo el documento XML en la memoria para analizarlo. SAX es más eficiente en memoria que DOM.

DOM también tiene sus beneficios. Por ejemplo, DOM es compatible con XPath. También facilita la operación en todo el árbol de documentos a la vez, ya que el documento se carga en la memoria .

4. SAX vs StAX

StAX es más reciente que SAX y DOM. Significa Streaming API para XML .

La principal diferencia con SAX es que StAX usa un mecanismo de tracción en lugar del mecanismo de empuje de SAX (usando devoluciones de llamada).

Esto significa que el cliente tiene el control para decidir cuándo es necesario extraer los eventos. Por lo tanto, no hay obligación de extraer todo el documento si solo se necesita una parte.

Proporciona una API sencilla para trabajar con XML con una forma de análisis que ahorra memoria.

A diferencia de SAX, no proporciona la validación de esquemas como una de sus características.

5. Análisis del archivo XML mediante un controlador personalizado

Usemos ahora el siguiente XML que representa el sitio web de Baeldung y sus artículos:

   Parsing an XML File Using SAX Parser SAX Parser's Lorem ipsum...   Parsing an XML File Using DOM Parser DOM Parser's Lorem ipsum...   Parsing an XML File Using StAX Parser StAX's Lorem ipsum...   

Comenzaremos creando POJO para nuestro elemento raíz Baeldung y sus hijos:

public class Baeldung { private List articleList; // usual getters and setters } 
public class BaeldungArticle { private String title; private String content; // usual getters and setters } 

Continuaremos creando BaeldungHandler . Esta clase implementará los métodos de devolución de llamada necesarios para capturar los eventos.

Anularemos cuatro métodos de la superclase DefaultHandler, cada uno caracterizando un evento:

    • characters (char [], int, int) recibe caracteres con límites. Los convertiremos a String y lo almacenaremos en una variable de BaeldungHandler
    • startDocument () se invoca cuando comienza el análisis; lo usaremos para construir nuestra instancia de Baeldung
    • startElement () se invoca cuando comienza el análisis para un elemento; lo usaremos para construir instancias List o BaeldungArticle ; qName nos ayuda a hacer la distinción entre ambos tipos
    • endElement () se invoca cuando finaliza el análisis de un elemento; aquí es cuando asignaremos el contenido de las etiquetas a sus respectivas variables

Con todas las devoluciones de llamada definidas, ahora podemos escribir la clase BaeldungHandler :

public class BaeldungHandler extends DefaultHandler { private static final String ARTICLES = "articles"; private static final String ARTICLE = "article"; private static final String TITLE = "title"; private static final String CONTENT = "content"; private Baeldung website; private String elementValue; @Override public void characters(char[] ch, int start, int length) throws SAXException { elementValue = new String(ch, start, length); } @Override public void startDocument() throws SAXException { website = new Baeldung(); } @Override public void startElement(String uri, String lName, String qName, Attributes attr) throws SAXException { switch (qName) { case ARTICLES: website.articleList = new ArrayList(); break; case ARTICLE: website.articleList.add(new BaeldungArticle()); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { switch (qName) { case TITLE: latestArticle().title = elementValue; break; case CONTENT: latestArticle().content = elementValue; break; } } private BaeldungArticle latestArticle() { List articleList = website.articleList; int latestArticleIndex = articleList.size() - 1; return articleList.get(latestArticleIndex); } public Baeldung getWebsite() { return website; } } 

También se han agregado constantes de cadena para aumentar la legibilidad. También es conveniente un método para recuperar el último artículo encontrado. Finalmente, necesitamos un captador para el objeto Baeldung .

Tenga en cuenta que lo anterior no es seguro para subprocesos, ya que nos aferramos al estado entre las llamadas al método.

6. Prueba del analizador

Para probar el analizador, crearemos una instancia de SaxFactory , SaxParser y también BaeldungHandler :

SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); SaxParserMain.BaeldungHandler baeldungHandler = new SaxParserMain.BaeldungHandler(); 

Después de eso, analizaremos el archivo XML y afirmaremos que el objeto contiene todos los elementos esperados analizados:

saxParser.parse("src/test/resources/sax/baeldung.xml", baeldungHandler); SaxParserMain.Baeldung result = baeldungHandler.getWebsite(); assertNotNull(result); List articles = result.getArticleList(); assertNotNull(articles); assertEquals(3, articles.size()); SaxParserMain.BaeldungArticle articleOne = articles.get(0); assertEquals("Parsing an XML File Using SAX Parser", articleOne.getTitle()); assertEquals("SAX Parser's Lorem ipsum...", articleOne.getContent()); SaxParserMain.BaeldungArticle articleTwo = articles.get(1); assertEquals("Parsing an XML File Using DOM Parser", articleTwo.getTitle()); assertEquals("DOM Parser's Lorem ipsum...", articleTwo.getContent()); SaxParserMain.BaeldungArticle articleThree = articles.get(2); assertEquals("Parsing an XML File Using StAX Parser", articleThree.getTitle()); assertEquals("StAX Parser's Lorem ipsum...", articleThree.getContent()); 

Como era de esperar, el baeldung se ha analizado correctamente y contiene los subobjetos esperados.

7. Conclusión

Acabamos de descubrir cómo usar SAX para analizar archivos XML. Es una API poderosa que genera una pequeña huella de memoria en nuestras aplicaciones.

Como de costumbre, el código de este artículo está disponible en GitHub.