# Riesen-XML-Datei verarbeiten



## de_hans (14. Mrz 2007)

hallo zusammen,

ich habe die aufgabe bekommen XML dateien zu verändern/manipulieren, das problem daran, die dateien sind zwischen  8GB-14GB groß!
da ich großen zeitdruck hatte und wußte das die einzelnen elemente immer schön mit zeilenumbruch untereinander stehen, verarbeite ich diese im moment wie eine textdatei(ich weiß, ich weiß, ist nicht wirklich toll, aber es funktioniert).
heißt, ich benutze BufferedReader, BufferedWriter, PrintWriter - fange meine Elemente mit contains ab, speichere blöcke/knoten in ArrayLists zwischen. alles wunderbar, sogar die laufzeiten halten sich in grenzen(bei einfachen suchmustern 30-45min, bei komplexeren 1,5h). 
so, nun kann es aber sein das die datei ohne jeglichen zeilenumbruch kommt, also kann ich mein miniprogrämmle in die tonne treten und muss was neues tippen.

mal ein Bsp für meine aufgabe:

ich soll das attribut att1 von elem2 auf 'J' ändern wenn att1 von elem7=1 und att1 von elem12=1, wenn aber att1 von elem elem12=3 dann soll z.b.: das ganze elem1 entfernt werden oder z.b. elem2 entfernt werden!


```
<xml>
	<elem1 att1="12" att2="1">
		<elem2 att1="N"/>
		<elem3 att1="1">
			<elem4 att1="F"/>
			<elem5 att1="!">
				<elem6>
					<elem7 att1="1"/>					
				</elem6>
			</elem5>
			<elem8 att1="aa" att2="4">
				<elem9>
					<elem10 att1="1"/>
					...usw...
				</elem9>
			</elem8>			
		</elem3>
		<elem11>
			<elem12 att1="1"/>
			<elem13>
				...usw
			</elem13>
		</elem11>		
	</elem1>
</xml>
```


deswegen jetzt meine frage zum generellen vorgehen.

ich muss dazusagen das ich bei der XML verarbeitung in java absoluter neuling bin und nicht so richtig weiß wie ich das machen soll. ich dachte mir jedenfalls das ich den SAX schonmal zum einlesen benötige(?), ist doch die einzige möglichkeit ne XML datei sequentiell einzulesen, oder???
aber wie bekomm ich das mit sax wieder raus? der kann doch gar nicht schreiben, oder?
kann ich irgendwie sax - mit DOM,JDOM kombinieren?

wie würdet ihr vorgehen?
habt ihr nen vorschlag? wäre superdankbar!!!

viele grüße


----------



## KSG9|sebastian (14. Mrz 2007)

Ne XML-Datei in Gigabyte-Größe? Das ist nicht euer ernst, oder? Was macht ihr denn mit dem Teil? Serialisiert ihr HDTV-Filme rein? *G*

Also ich bezweifel dass du mit XML-Parsen wirklich ne Chanche hast. JDOM kannste vergessen da der Baum deinen Speicher sprengen wird, evtl. SAX..
Gruß


----------



## de_hans (14. Mrz 2007)

das sind abrechnungsdaten von insgesamt über 3500 kunden, die aber in einer datei zusammengefasst werden müssen!!!
ursprünglich hat jeder kunde eine eigene datei(ca 4-4.5MB) diese müssen aber zu einer gesamtdatei zusammengefasst werden! jetzt könnte man ja meinen ich sollte einfach auf die ursprungsdateien gehen und diese manipulieren!? das geht auch nicht, weil die gesamtdatei noch von einem weiteren programm(von einer externen firma) weiterverarbeitet werden muss. über diese *finale* Version läuft eine prüfung und dann soll mein programm kommen(würde unglaublich viel zeit kosten an dieser stelle nochmal vorne bei den einzeldateien anzusetzen!!!)!


----------



## Lim_Dul (14. Mrz 2007)

Mit Sax wirst du sie vermutlich einlesen können.

Schreiben geht in Java direkt afaik nur über DOM, wofür die XML Datei komplett im Speicher vorher seun muss - kannst du also vergessen. Das heißt, du wirst aufbauend auf dem Sax-parser vemutlich eine eigene Speicherroutine schreiben müssen.


----------



## Guest (16. Mrz 2007)

> nun kann es aber sein das die datei ohne jeglichen zeilenumbruch kommt, also kann ich mein miniprogrämmle in die tonne treten und muss was neues tippen.



wieso hast du damit ein Problem??


----------



## de_hans (16. Mrz 2007)

Anonymous hat gesagt.:
			
		

> > nun kann es aber sein das die datei ohne jeglichen zeilenumbruch kommt, also kann ich mein miniprogrämmle in die tonne treten und muss was neues tippen.
> 
> 
> 
> wieso hast du damit ein Problem??



weil ich bis jetzt diese XML datei wie eine textdatei zeilenweise eingelesen habe!!! und das kann ich ohne zeilenumbrüche vergessen, außerdem isses einfach nicht sauber programmiert.    

hat keiner noch irgendeinen vorschlag????


----------



## Gooose (19. Mrz 2007)

Ach wenn's nur das ist, vielleicht hilft dir die Klasse etwas weiter.

Im Jdom gibt es mehrere Methoden dein Document darzustellen, ich denke getPrettyFormat() oder getRawFormat() sollten dir weiterhelfen - zumindest was den Zeilenumbruch betrifft.

Im DOM4J gibt es ebenfalls eine Methode zu Darstellung eines Document in XML-Struktur - asXML().


```
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.util.List;

import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.jdom.input.SAXBuilder;


public class Test_JDOM {
    
    public Test_JDOM(){
    }
    
    public static void main(String Args[]){
        readXMLDocument();
    }
    
    public static void readXMLDocument() { 

        try { 
	       
            URL url = new URL("file:///C://Temp//Test.xml");
    		InputStream isXML = new FileInputStream(new File(url.getPath()));

            SAXBuilder sBuilder = new SAXBuilder();
		    Document document = sBuilder.build(isXML); 
         
//		    readElement(document.getRootElement());
		    
	        FileWriter ausgabestrom = new FileWriter("c://Temp//JDOM_Test_001.xml");
		    XMLOutputter xoutC = new XMLOutputter( Format.getCompactFormat() );
		    XMLOutputter xoutP = new XMLOutputter( Format.getPrettyFormat() );
		    XMLOutputter xoutR = new XMLOutputter( Format.getRawFormat() );
		    xoutC.output( document, System.out ); 
		    xoutP.output( document, ausgabestrom ); 
		    xoutR.output( document, System.out ); 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    }
    
    public static Element readElement(Element eElement) {

        List listeElemente = eElement.getChildren();
	    
	    for (int i = 0 ; i < listeElemente.size(); i++){
	        Element eElement1 = (Element) listeElemente.get(i);
//	        System.out.println(eElement1.getName() + " T: " + ((eElement1.getTextTrim()==null)?"leer":eElement1.getTextTrim()));
	        readElement(eElement1);
	        if (eElement1.getAttributes() != null ) {
	            readAttribute(eElement1);
	        }
	    }
        
        return eElement;
    }

    public static void readAttribute(Element eElement) {

        List listeAttribute = eElement.getAttributes();
	    
	    for (int i = 0 ; i < listeAttribute.size(); i++){
	        Attribute aAttribute = (Attribute) listeAttribute.get(i);
//	        System.out.println( "  A: " + aAttribute.getName() + " W: " + aAttribute.getValue());
	    }
        
    }
    

}
```

Gruuuss
Gooose


----------



## Roar (19. Mrz 2007)

@Gooose: da hast du wohl was falsch verstanden, er hat kein problem damit xml ausgeben sondern einzulesen.
@Sebastian: xml dateien in gb größe sind doch nichts außergewöhnliches, auch wenn 14gb schon nich schlecht ist 
@hans: versuchs mit stax


----------



## Gooose (19. Mrz 2007)

> so, nun kann es aber sein das die datei ohne jeglichen zeilenumbruch kommt, also kann ich mein miniprogrämmle in die tonne treten und muss was neues tippen.



Hallo roar,

was soll ich an diesem Satz falsch verstanden haben. Wenn er seine XML-Dateien damit einliest und einheitlich (mit Zeilenumbruch) neu schreibt, braucht er sein "miniprogrämmle" nicht in die Tonne treten.


Gruuus

Gooose


----------



## Roar (19. Mrz 2007)

so, nun soll er jetzt seine xml datei einlesen, parsen, und wieder ausgeben, damit er sie dann wieder einlesen kann? ???:L
zumal das mit jdom gar nich möglich ist seine 14gb datei einzulesen


----------

