Categorías
StAX

Java: leer XML grande mediante StAX

El siguiente código muestra cómo leer un archivo XML en Java. Utiliza la API StAX que lee archivos xml de forma secuencial. Si desea leer un archivo xml grande y obtener un error de memoria, debería poder resolver el problema utilizando el código siguiente. La siguiente solución lee el archivo xml de forma secuencial y puede procesar archivos xml muy grandes, como 10G o 20G. Por tanto, ¡es una solución escalable!

Problema

Del siguiente archivo xml, obtenga «id» y primero «thetext» de cada elemento. Esto está relacionado con cómo obtener los primeros elementos del archivo XML.

En la siguiente sección, completaré el código para analizar el archivo xml usando StAX y explicaré el código un poco.

<?xml version="1.0" encoding="UTF-8"?>
<config>
	<item id="1">
		<mode>1</mode>
		<long_desc isprivate="0">
			<who name="Andy">[email protected]</who>
			<bug_when>2001-10-10 21:34:46 -0400</bug_when>
			<thetext> Setup a project</thetext>
		</long_desc>
 
		<long_desc isprivate="0">
			<who name="Mike">[email protected]</who>
			<bug_when>2001-10-10 21:34:46 -0400</bug_when>
			<thetext>- Setup</thetext>
		</long_desc>
		<long_desc isprivate="0">
			<who name="Gary">[email protected]</who>
			<bug_when>2001-10-10 21:34:46 -0400</bug_when>
			<thetext>project</thetext>
		</long_desc>
 
	</item>
 
	<item id="2">
		<mode>2</mode>
		<long_desc isprivate="0">
			<who name="John">[email protected]</who>
			<bug_when>2001-10-10 21:34:46 -0400</bug_when>
			<thetext> Setup a project</thetext>
		</long_desc>
 
		<long_desc isprivate="0">
			<who name="Bill">[email protected]</who>
			<bug_when>2001-10-10 21:34:46 -0400</bug_when>
			<thetext>- Setup</thetext>
		</long_desc>
 
		<long_desc isprivate="0">
			<who name="Rick">[email protected]</who>
			<bug_when>2001-10-10 21:34:46 -0400</bug_when>
			<thetext>project</thetext>
		</long_desc>
 
	</item>
</config>
  Código Java: use StAX para crear un archivo xml

Solución

Código completo:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Iterator;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
 
class Item{
	private String firstText = null;
 
	public void setFirstText(String str){
		firstText =  str;
	}
 
	public String getFirstText(){		
		if(firstText == null){
			return null;
		}else{
			return firstText;
		}
	}
}
 
public class Main {
	public static void main(String[] args) throws FileNotFoundException,
			XMLStreamException, FactoryConfigurationError {
		// First create a new XMLInputFactory
		XMLInputFactory inputFactory = XMLInputFactory.newInstance();
 
		//inputFactory.setProperty("javax.xml.stream.isCoalescing", True)
 
		// Setup a new eventReader
		InputStream in = new FileInputStream("/usa/xiwang/Desktop/config");
		XMLEventReader eventReader = inputFactory.createXMLEventReader(in);
 
		Item item = null;
 
		while (eventReader.hasNext()) {
			XMLEvent event = eventReader.nextEvent();
 
			//reach the start of an item
			if (event.isStartElement()) {
 
				StartElement startElement = event.asStartElement();
 
				if (startElement.getName().getLocalPart().equals("item")) {
					item = new Item();
					System.out.println("--start of an item");
					// attribute
					Iterator<Attribute> attributes = startElement.getAttributes();
					while (attributes.hasNext()) {
						Attribute attribute = attributes.next();
						if (attribute.getName().toString().equals("id")) {
							System.out.println("id = " + attribute.getValue());
						}
					}
				}
 
				// data
				if (event.isStartElement()) {
					if (event.asStartElement().getName().getLocalPart().equals("thetext")) {
						event = eventReader.nextEvent();
 
						if(item.getFirstText() == null){
							System.out.println("thetext: "
									+ event.asCharacters().getData());
							item.setFirstText("notnull");
							continue;
						}else{
							continue;
						}
 
					}
				}
			}
 
			//reach the end of an item
			if (event.isEndElement()) {
				EndElement endElement = event.asEndElement();
				if (endElement.getName().getLocalPart() == "item") {
					System.out.println("--end of an itemn");
					item = null;
				}
			}
 
		}
	}
}
  StAX: Obtener EntityReferences en un archivo XML

La solución para obtener el primer contenido «thetext» es crear un objeto cuando se lee el inicio de un elemento «item», asignar contenido «thetext» a uno de sus miembros solo cuando su miembro está vacío. Esto asegura que sólo se almacenen los primeros datos «thetext».

En resumen, la API de StAX es conveniente de usar, pero aún así se necesita algo de tiempo para comprender cómo Evento conducido funciona y por qué cuesta menos memoria.

Aquí está el tutorial de Java EE de Oracle. http://download.oracle.com/javaee/5/tutorial/doc/bnbec.html#bnbeh

Por Programación.Click

Más de 20 años programando en diferentes lenguajes de programación. Apasionado del code clean y el terminar lo que se empieza. ¿Programamos de verdad?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *