# DOM Parser



## Stephan2009 (7. Jul 2009)

Habe einen Dom Parser geschrieben und zwar so :


```
/** This Main function parsed the XML file into file and transform it from parsing into new XML file 
     * @throws IOException 
     *
     */
    public static void parsebyDom() throws TransformerConfigurationException, IOException{
    	
    	Document doc = parseFile("ResortManagement.xml");
 	   // get root node of xml tree structure
 	   Node root = doc.getDocumentElement();
 	   // write node and its child nodes into file
 	        writeDocument(root,0);
 	         // write Document into XML file
 	        saveXMLDocument("dom2.xml.xml", doc);
		    
	}
	
    /** This Main function load the transformed XML File 
     *
     */
	
    public static void load() throws IOException,FileNotFoundException {
		FileReader filereader = new FileReader("dom2.xml.xml");
		BufferedReader bufferedreader = new BufferedReader(filereader);

		String line = bufferedreader.readLine();
		
		while (line != null) {

			line = bufferedreader.readLine();
			System.out.println(line);
		}

		bufferedreader.close();
		filereader.close();
		
	}
	
	     /** Returns element value
	      * @param elem element 
	      * @return Element value otherwise empty String
	      */
     public final static String getElementValue( Node elem ) {
	         Node kid;
         if( elem != null){
	            if (elem.hasChildNodes()){
	                 for( kid = elem.getFirstChild(); kid != null; kid = kid.getNextSibling() ){
	                    if( kid.getNodeType() == Node.TEXT_NODE  ){
	                         return kid.getNodeValue();
	                    }
	                }
	             }
	         }
	         return "";
	     }
         
         // For Formated Output 
	     private static String getIndentSpaces(int indent) {
	        StringBuffer buffer = new StringBuffer();
	         for (int i = 0; i < indent; i++) {
	             buffer.append(" ");
	         }
	         return buffer.toString();
	     }
	    
	/** Writes node and all child nodes into System.out
	  * @param node XML node from from XML tree 
      * @param indent number of spaces used to indent output
	 * @throws IOException 
	      */
	    public static void writeDocument(Node node,int indent) throws IOException {
	        
	    	FileWriter out=new FileWriter("parsed_xml.xml");
	    	BufferedWriter write=new BufferedWriter(out);
	    	
	    	// get element name
        String nodeName = node.getNodeName();
	        // get element value
         String nodeValue = getElementValue(node);
        // get attributes of element
	         NamedNodeMap attributes = node.getAttributes();
        System.out.println(((getIndentSpaces(indent) + "NodeName: " + nodeName + ", NodeValue: " + nodeValue)));
	        for (int i = 0; i < attributes.getLength(); i++) {
	            Node attribute = attributes.item(i);
	          System.out.println(((getIndentSpaces(indent + 2) + "AttributeName: " + attribute.getNodeName() + ", attributeValue: " + attribute.getNodeValue())));
	        }
	         // write all child nodes recursively
	         NodeList children = node.getChildNodes();
	        for (int i = 0; i < children.getLength(); i++) {
	             Node child = children.item(i);
	             if (child.getNodeType() == Node.ELEMENT_NODE) {
	               writeDocument(child,indent + 2);
	             }
         }
	     }
	     
	/** Saves XML Document into XML file.
      * @param fileName XML file name
      * @param doc XML document to save
	 * @throws TransformerConfigurationException 
	 * @throws FileNotFoundException 
	  *
	  */    
	    public static boolean saveXMLDocument(String fileName, Document doc) throws TransformerConfigurationException, FileNotFoundException {
	         System.out.println("Saving XML file... " + fileName);
	         // open output stream where XML Document will be saved
             File xmlOutputFile = new File(fileName);
	     	      	         
	       FileOutputStream fos = new FileOutputStream(xmlOutputFile);
         
	      // Use a Transformer for output
	      TransformerFactory transformerFactory = TransformerFactory.newInstance();
	      
           Transformer transformer = transformerFactory.newTransformer();
	        
            DOMSource source = new DOMSource(doc);
	        StreamResult result = new StreamResult(fos);
	       
	        try {
	            transformer.transform(source, result);
	       }
	        catch (TransformerException e) {
	            System.out.println("Error transform: " + e.getMessage());
	        }
	        System.out.println("XML file saved.");
	        return true;
	    }
	     
	    /** This function Parses XML file 
	      * @param fileName XML file to parse
	      * @return XML document 
	      */
	    public static Document parseFile(String fileName) {
	         System.out.println("Parsing XML file... " + fileName);
	         DocumentBuilder docBuilder;
	         Document doc = null;
	         DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
	         docBuilderFactory.setIgnoringElementContentWhitespace(true);
	         try {
             docBuilder = docBuilderFactory.newDocumentBuilder();
	         }
	        catch (ParserConfigurationException e) {
	             System.out.println("Wrong parser configuration: " + e.getMessage());
	             return null;
	         }
	         File sourceFile = new File(fileName);
	         try {
            doc = docBuilder.parse(sourceFile);
            
	        }
	        catch (SAXException e) {
	            System.out.println("XML file structure is wrong !: " + e.getMessage());
	             return null;
	         }
	        catch (IOException e) {
	            System.out.println("Could not find file: " + e.getMessage());
	         }
	        System.out.println("XML file parsed");
	         return doc;
	   }
	     
	    // Main method for Testing
	     public static void main(String[] args) throws TransformerConfigurationException, IOException {
	        	        
	        ParsedbyDom.parsebyDom();
	        ParsedbyDom.load();
	     }
	     
	 }
```

Funktioniert auch wunderbar allerdings habe ich versucht die geparste Ausgabe auf der Konsole in eine Datei zu schreiben aber das geht nicht kann mir da jemand helfen? 

Also anstatt der System.out .... soll die Ausgabe in einer Datei erscheinen hab dazu den FileWriter genutzt


----------



## SlaterB (7. Jul 2009)

Zeile 84
 System.out.println( ........);

ändern in 

write.write( .... );
write.write("\n");

?

am Ende nicht das close() auf den Stream vergessen


----------



## Stephan2009 (7. Jul 2009)

Hallo danke 

Das hab ich so gemacht allerdings schreibt er nicht das geparste in die datei sondern andere Daten , ich muss doch einfach nur writer.close(); noch setzen oder?


----------



## SlaterB (7. Jul 2009)

close + die write-Befehle, genau

was in die Datei reinkommt, hängt genau von den write-Befehlen ab,
was soll man spontan dazu sagen?
du musst doch wissen womit du die Methoden aufrufst, kannst ja nebenbei noch alles in die Konsole loggen usw.


----------



## Stephan2009 (7. Jul 2009)

Also ich habe das so gemacht :


```
FileWriter write=new FileWriter("parsed_xml.xml");
	    	
	    	
	    	// get element name
        String nodeName = node.getNodeName();
	        // get element value
         String nodeValue = getElementValue(node);
        // get attributes of element
	         NamedNodeMap attributes = node.getAttributes();
	         write.write(getIndentSpaces(indent) + "NodeName: " + nodeName + ", NodeValue: " + nodeValue);
	         
	        
	         for (int i = 0; i < attributes.getLength(); i++) {
	            Node attribute = attributes.item(i);
	            
	            write.write(getIndentSpaces(indent + 2) + "AttributeName: " + attribute.getNodeName() + ", attributeValue: " + attribute.getNodeValue());
	            
	            
	        }
	         
	        
	        // write all child nodes recursively
	         NodeList children = node.getChildNodes();
	        for (int i = 0; i < children.getLength(); i++) {
	             Node child = children.item(i);
	             if (child.getNodeType() == Node.ELEMENT_NODE) {
	               writeDocument(child,indent + 2);
	               
	             }
	              
	        }
	        write.close();
	    }
```

Normalerweise sollte er jetzt die gesamte Datei parsen und die geparste Datei durch den Writer in die Datei schreiben das macht er aber nicht wo kann der Fehler liegen?


----------



## SlaterB (7. Jul 2009)

du rufst die Methode rekursiv auf, jedesmal wird ein neuer Writer angelegt, der die vorherige Datei überschreibt,
bzw., da die close() ineinander verschachtelt sind, wer weiß was schlimmes macht,

öffne nur einen Writer und übergib den als Parameter, z.B.


```
writeToFile(Root) {
  Writer ..
  writeToFileRec(writer, node);
  close();
}

writeToFileRec(Writer, Node) {
  write ..
  for Childs: 
      writeToFileRec(writer, child);
}
```


----------



## Stephan2009 (7. Jul 2009)

Versteh ich nicht kannst du mir das etwas genauer erklären was du meinst?


----------



## SlaterB (7. Jul 2009)

wenn du 

> if (child.getNodeType() == Node.ELEMENT_NODE) {
>                   writeDocument(child,indent + 2);
>                 }

für die Kinder ausführst, wird die Methode writeDocument neu gestartet 
-> ein neuer FileWriter angelegt, der die Datei neu beschreibt, das vorherige löscht


----------



## Stephan2009 (7. Jul 2009)

Ach soo ja ok das stimmt  wie sollte ich das dann am besten lösen?


----------



## SlaterB (7. Jul 2009)

eine gute Frage, 
drehen wir die Zeit 30 Min. zurück:



SlaterB hat gesagt.:


> öffne nur einen Writer und übergib den als Parameter, z.B.
> 
> 
> ```
> ...


----------



## Stephan2009 (7. Jul 2009)

Ginge evtl auch den System.out Strom in eine Datei zu speichern?


----------



## SlaterB (7. Jul 2009)

oh ja, 
System.setOut(neuer PrintStream, der auf eine Datei zeigt) (evtl. bei google suchen)

ober aber, um auch die Parameter zu ersparen, definiere dir ein Klassenattribut/ eine statische Variable mit dem Writer und greife dann darauf zu,
das Anlegen + close() irgendwo zentral, z.B. in der main-Methode oder in 
parsebyDom()

auch bei System.setOut() close() nicht vergessen am Ende


----------



## Stephan2009 (7. Jul 2009)

Hat sich erledigt habs 

System.setOut(new PrintStream(new FileOutputStream("output.txt",true)));

Ist doch so einfacher


----------

