Große XML-Datei validieren

lubu

Mitglied
Hi,

ich suche eine Möglichkeit große XML-Dateien zu validieren. Ich habe schon einen Artikel hinsichtlich "Große XML-Files parsen" in der tutorials-DB gefunden. Aber ich möchte die XML-Datei nicht nur parsen sondern auch validieren, so wie es in dem genannten Beispiel gemacht wird. Oder wird mein Problem dabei gleich mit erledigt?

In meinem Szenario verarbeite ich eine ca. 140 MB große XML-Datei mittels JDOM und lese dabei den gesamten Tree ein. Klar das dabei eine entsprechende Java-Fehlermeldung auftaucht, obwohl ich den Heap schon auf 512 MB gesetzt habe.

Tschau
Lutz
 
Hallo,

also soweit ich weiß, kann man mit einem SAXParser auch validieren. Ist JDOM ein muss bei dir? Sonst würde ich vorschlagen, dass du mit dem SAXParser von java oder einem anderen das XML-File parst und gleichzeitig validierst.

MFG

zEriX
 
Hi,

ich validiere andere kleinere XML-Dateien schon mittels JDOM und verwende dabei den SAX-Parser. Allerdings bricht das Einlesen mit einem OutOfMemoryError ab aufgrund der Grösse ab. Im Folgende habe ich das Beispiel zum Parsen von großen XML-Dateien von Thomas Darimont aufgelistet: (Dieses Beipiel ist für meine Zwecke gut geeignet, allerdings weiß ich halt nicht, ob im Zuge des Parsens auch validiert wird.)


Hallo!

Es bestünde die Möglichkeit der Java Laufzeit mittels der Parameter -Xms und -Xmx
mehr Speicher zur Verfügung zu stellen. ZBsp.:
-Xms64m
-Xms256m

Wie verarbeitest du denn das Dokument? "Fasst" du wirklich jedes Element an? Normalerweise verwenden "schlaue" XML Parser die Technik der "deferred Node initialization". Damit werden Objekt-Repräsentationen für XML Elemente erst dann gebaut, wenn wirklich auf das Element zugegriffen wird. Wenn du auf alle Elemente zugreifst solltest du vielleicht deinen Parse-Vorgang "optimieren". Z.Bsp. indem du ElementHandler implementierst welche während des Parsens auf bestimmte Elemente (die die dich interessieren) reagieren und für jedes Element eine Behandlungsroutine aufruft.

Bsp.:

Code:
/**
 * 
 */
package de.tutorials;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;

/**
 * @author Tom
 */
public class XMLTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		BufferedWriter bw = new BufferedWriter(new FileWriter("c:/foo.xml"));

		// Dummy XML Datei erstellen:
		// foo.xml -> 36.666.704 foo.xml (~36 MB)

		bw.write("<?xml version=\"1.0\"?>");
		bw.write("<root>");
		for (int i = 0; i < 1000000; i++) {
			bw.write("<element" + i + ">");
			bw.write(String.valueOf(i));
			bw.write("</element" + i + ">");
		}
		bw.write("</root>");
		bw.flush();
		bw.close();

		SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
		parser.parse(new File("c:/foo.xml"), new DefaultHandler() {
			public void startElement(String uri, String localName,
					String qName, Attributes attributes) {
				System.out.print(qName);
				System.out.print(": ");
			}

			public void characters(char[] ch, int start, int length) {
				char[] tmp = new char[length];
				System.arraycopy(ch,start,tmp,0,length);
				System.out.println(new String(tmp));
			}

		});

	}
}

Wenn du nur einen kleinen Ausschnitt aus dem Export benötigst wäre XPath auch recht hilfreich.

Gruß Tom

Tschau Lutz
 
Das bei JDOM ist meiner Meinung nach nicht wirklcih ein SAXParser, weil am Ende ein DOM-Baum erstellt wird. Ein richtiger SAXParser läuft über das XML-File und du kannst bei jedem Knoten was machen.

Das Beispiel von Tom ist ein SAXParser, mit diesem kannst du auch validieren. Hier ist mal ein Beispiel wie du mit dem SAXParser gegen ein externes Schema validierst.

Java:
/**
 * 
 */


import java.io.File;

import javax.xml.XMLConstants;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

/**
 * 
 *
 */
public class SimpleSax {
	
	public SimpleSax() throws Exception{
		parse("test.xml");
	}
	
	public void parse(String file) throws Exception{
		SAXParserFactory factory = SAXParserFactory.newInstance();
		
		SchemaFactory factory2 = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
		Schema schema = factory2.newSchema(new File("test.xsd"));
		factory.setNamespaceAware(true);
		
		factory.setValidating(false);
		factory.setSchema(schema);
		
		SAXParser parser = factory.newSAXParser();

		parser.parse(new File(file), new SaxHandler());
	}
	
	public static void main(String[] args) {
		try {
			new SimpleSax();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


Java:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

public class SaxHandler extends DefaultHandler {

	SaxNode node;
	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		node.showAll();
	}

	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.startDocument();
	}

	@Override
	public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException {
		node = SaxNode.getInstance(arg2);
		node.increment();
	}

	@Override
	public void error(SAXParseException arg0) throws SAXException {
		// TODO Auto-generated method stub
		System.out.println(arg0);
	}

	@Override
	public void fatalError(SAXParseException arg0) throws SAXException {
		// TODO Auto-generated method stub
		System.out.println(arg0);
	}

	@Override
	public void warning(SAXParseException arg0) throws SAXException {
		// TODO Auto-generated method stub
		System.out.println(arg0);
	}

}


Das müsste dir eigentlich helfen. Das ganze ist mit dem SAXParser der von Haus aus bei JAVA dabei ist.

MFG

zEriX
 
Zuletzt bearbeitet:
Zurück