# XML-File verabeiten



## mathon (19. Sep 2006)

hallo,


ich habe ein XML-File und möchte für dieses gerne mit Hilfe eines kleinen Java-Programms ein HTML-Output-File generieren, wo dann die einzelnen Daten des XML-Files in einer Tabelle dargestellt werden. 

Hat jemand von euch Tipps für mich, wie ich das am einfachsten realisiere bzw. gibts vielleicht Tutorials oder Beispiele hierfür?

lg matti


----------



## Wildcard (19. Sep 2006)

Am einfachsten geht das mit JDom


----------



## Roar (19. Sep 2006)

ne am einfachsten geht das mit xsl


----------



## Wildcard (19. Sep 2006)

oder EMF  :bae:


----------



## mathon (19. Sep 2006)

Hi,

danke für die replies, ja ich sollte es eigentlich mit JDom machen. Gibts dazu Tutorials oder SampleCode?

lg matti


----------



## Wildcard (19. Sep 2006)

http://www.galileocomputing.de/open...sel13_005.htm#Rxx747java130050400047F1F03B100


----------



## Roar (19. Sep 2006)

mit jdom kannst auch xsl benutzen


----------



## mathon (19. Sep 2006)

Okay alles klar, nur wenn ich das XML-File eingelesen habe, gibt es da auch spezielle Methoden wie ich dann mit den Informationen aus dem XML-File ein Output-file erzeugen kann...?


----------



## Roar (19. Sep 2006)

joho
XSLTransformer t = new XSLTransformer(meinXslFile);
Document html = t.transform(meinXmlDocument);

dann kannst dat html mit nem XMLOutputter rausschreiben.

info zu xsl gibs z.b. hier: http://w3schools.com/xsl/xsl_intro.asp


----------



## Wildcard (19. Sep 2006)

Ich nehm dir gleich den Smiley weg  :bae:


----------



## mathon (20. Sep 2006)

Hmm...steh da jetzt noch ein bißchen an, bin in java zwar kein neuling, habe aber mit xml+java noch nichts gemacht. wie meinst du das genau mit dem XSLTransformer? - dafür brauch ich ja wieder ein eigenes package oder, das ist ja in dem jdom package von apache nicht dabei oder?


----------



## Roar (20. Sep 2006)

ne alder den brauch isch, bin isch doch voll der krasso checker pro nä 
	

	
	
		
		

		
		
	


	




edit:
XSLTransformer ist von jdom
und jdom is nich von apache


----------



## mathon (20. Sep 2006)

Hi,


ups sorry, das läuft anscheinend nur unter der Apache-Lizenz. Okay, 

1) Okay also wenn ich die Transformation mit einem XSL-Stylesheet mache erstelle ich mir einfach zu dem XML-File ein XSL-Stylesheet dazu und schreibe eine Java-Klasse die folgendes macht:



```
XSLTransformer t = new XSLTransformer("c:\books.xsl");
Document html = t.transform("c:\books.xsl"); 
new XMLOutputter().output(html, "c:\books.html");
```

Ist das so korrekt?

2) Ist es anders nicht möglich, wenn ich per JDom ein XML-File einlese, dass ich es in ein HTML-File rausschreibe, ohne ein XSL-File zu verwenden?


Wäre super wenn du mir nochmal antworten könntest. :? 

lg matti


----------



## Roar (20. Sep 2006)

der code is nich so ganz korrekt, transform() erwartet dein XML Document, ansonsten schon glaub.

2) doch klar, aber is voll der noob aufwand mit string zusammenbatschen und voll :bloed: wenns doch dafür extra sowat krassomatisches wie xsl gibt


----------



## mathon (20. Sep 2006)

okay , nur würde ich es gerne auf beide Arten durchführen...Wie könnte das nur beispielhaft aussehen, wenn ich ein XML-File ohne ein XSL-Stylesheet, formatiiert in eine HTML-Tabelle in ein HTML-Outputfile schreiben möchte?


----------



## Roar (20. Sep 2006)

kA wie deine xml datei aussieht aber dann irgendwie sowas eh:
sb.append("td").append(xmlElement.getAttributeValue("irgendwat").append("/td")...
und so nä
also ich würd dat lassen weil krampf und so


----------



## mathon (20. Sep 2006)

hmm...weiß jetzt nicht genau wie du das meinst...ich möchte ja dann die einzelnen Elemente des eingelesenen XML-Files in das HTML-Output-file schreiben bzw. die Elemente eben formatieren.

mein xml-file:


```
<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE buecher SYSTEM "booking.dtd">
<buecher>
     <buch sprache="deutsch">
         <titel>Der Zerbrochene Krug</titel>
         <autor>Heinrich v. Kleist</autor>
         <preis>40</preis>
         <identifizierung id="a1"/>
     </buch>
   <buch sprache="deutsch">
         <titel>Der Talismann</titel>
         <autor>Johann Nestroy </autor>
         <preis>30</preis>
         <identifizierung id="a2"/>
   </buch>
   <buch sprache="englisch">
         <titel>Ein Kind</titel>
         <autor>Thomas Bernhard</autor>
         <preis>60</preis>
         <identifizierung id="a3"/>
   </buch>		
</buecher>
```

Ich würde damit gerne ein HTML-Ouput-file erstellen in dem eine HTML-Tabelle existiert, wo der Titel, Sprache, Autor, Preis die Spalten darstellen und die Daten die Zeilen. 

Wie hast du das genau gemeint...? - sorry, dass ich nochmals nachfrage...

lg matti


----------



## huckfinn (20. Sep 2006)

Hi,

Im Prinzip läuft es darauf hinaus einen eigenen XML-Parser zu schreiben
und beim Auftreten eines Elementes und dessen Inhalte 
entsprechenden HTML-code zu erzeugen.  
Aber genau das macht das XSLT ja. Faktisch würdest du
das Fahrad noch mal erfinden. Aber was solls.  

Für das Parsen kann man entweder einen Objektbaum 
benutzen JDOM oder die Objekte zu Laufzeit behandeln,
das macht SAX. Ich bevorzuge SAX weil es den Speicher 
relativ in Ruhe läßt. Um deine Anwendung zu implementieren,
mußt du einen SAX ContentHandler schreiben.  Der implementiert
folgende Methoden.


```
package default;

import java.io.*;
import java.util.*;
import org.apache.commons.codec.binary.Base64;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.InputSource;

public class MyScanner implements ContentHandler {

    //--------------------------------------------------------------------------
     public MyScanner() {
        super();
        parser = new org.apache.xerces.parsers.SAXParser();
     }

    //--------------------------------------------------------------------------
   // Den Zugrif auf das Dokument schreibe ich schon mal rein
    public void parse(InputStream inputStream) throws SAXException {
        try {
            xmlStream = inputStream;
            parser.setFeature("http://xml.org/sax/features/validation",false);
            parser.setFeature("http://apache.org/xml/features/" +
                                  "nonvalidating/load-external-dtd",false);
            parser.setContentHandler(this);
            dataSource = new InputSource(xmlStream);
            parser.parse(dataSource);
        } catch (Exception e) {
           throw new SAXException("Kann den Datenstrom nicht öffnen! " +
                   "Details:"+e.getMessage());
        }  
    //--------------------------------------------------------------------------
    public void setDocumentLocator(Locator locator) {}

    //--------------------------------------------------------------------------
    public void startDocument() throws SAXException { ... alles initialisiern  }
    //--------------------------------------------------------------------------
    public void endDocument() throws SAXException { ... alles finales Zeug tun   }
    //--------------------------------------------------------------------------
    public void startPrefixMapping(String prefix, String uri)  throws SAXException {    }
    //--------------------------------------------------------------------------
    public void endPrefixMapping(String prefix) throws SAXException {    }
    //--------------------------------------------------------------------------
    public void startElement(String uri,  String localName, String qName, Attributes atts) throws SAXException { }
    //--------------------------------------------------------------------------
    public void characters(char[] ch, int start, int length) throws SAXException { }
    //--------------------------------------------------------------------------
    public void endElement(String uri, String localName, String qName) throws SAXException {  }
    //--------------------------------------------------------------------------
    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {  }
    //--------------------------------------------------------------------------
    public void processingInstruction(String target, String data) throws SAXException {}
    //--------------------------------------------------------------------------
    public void skippedEntity(String name) throws SAXException {}
}
```

Das sieht viel aus ist es auch!. Wichtig für uns sind die Methoden 


```
public void startElement(..
    public void characters(char[] ch, int start, int length ...
    public void endElement(..
```

Also ein kleines Beispiel das sich an deinen xml Code anlehnt
..nur ein kleines Beispiel kann so aussehen. Ich gehe davon 
aus das ich einen PrintWriter out habe um den Kram rauszuschreiben.


```
//--------------------------------------------------------------------------
    public void startDocument() throws SAXException {
         out.println("<html><body>")
    }
    //--------------------------------------------------------------------------
    public void endDocument() throws SAXException { 
         out.println("</body></html>")
    }
    //--------------------------------------------------------------------------
    public void startElement(String uri,
            String localName,
            String qName,
            Attributes atts) throws SAXException {
            if (localName.equals("Buecher")) {
                out.println("<table>");
                out.println("<tr>");
                out.println("<th>Titel</th><th>Author</th><th>Preis</th><th>ID</th>");
                out.println("/<tr>");
           }   else if  (localName.equals("buch")) out.println("<tr>");           
           }   else if  (localName.equals("titel")) out.println("<td>");           
           }   else if  (localName.equals("author")) out.println("<td>");           
           }   else if  (localName.equals("preis")) out.println("<td>");           
           }   else if  (localName.equals("identifizierung")) {
                out.println("<td>");           
                out.println(atts.getValue("id"));
           }
     }
    //--------------------------------------------------------------------------
    public void characters(char[] ch, int start, int length) throws SAXException {
       out.print(new String(ch,start,length));
    }
    //--------------------------------------------------------------------------
    public void endElement(String uri,
            String localName,
            String qName) throws SAXException {
           // Geht auch einfacher ..was solls
           if (localName.equals("Buecher")) out.println("</table>");
           }   else if  (localName.equals("buch")) out.println("</tr>");           
           }   else if  (localName.equals("titel")) out.println("</td>");           
           }   else if  (localName.equals("author")) out.println("</td>");           
           }   else if  (localName.equals("preis")) out.println("</td>");           
           }   else if  (localName.equals("identifizierung")) out.println("</td>");           
     }
```

Wie du siehst ein ganz schönes Gemodder und wenn du was 
umformatieren willst sehr unflexibel. 

Als denne Huck


[/code]


----------



## mathon (20. Sep 2006)

Danke für diese ausführliche Antwort. Eine kleine Verständnisfrage noch:

Brauche ich die MyScanner-Klasse? - ich könnte doch einfach per printwriter die einzelnen elemente meines durch jdom eingelesenen trees rausschreiben oder?

lg matti


----------



## huckfinn (20. Sep 2006)

Hi, 

Für SAX brauchst du die Implementierung MyScanner 
da diese ja nur ein Interface mit abstrakten Methoden 
weiter gibt.  Du mußt ja formulieren was du bei dem 
jeweilgen Ereignis "öffnen eines neuen Elementes"
"schließen eines offenen Elementes " während des
parsens tun willst .

Bei JDOM wird der Dokumentenbaum ja erzeugt
geparst und in einer Struktur abgespeichert. Diese
kannst du dann rekusiv durchlaufen, festellen welche
Knotentyp du hast und dann mit den jeweiligen 
out.println Anweisungen deinen HTML-Code 
erzeugen.

Noch eine Bemerkung. Das ablegen des Dokumentes 
oder besser der gesamten Dokumentenstruktur ist sehr 
speicherintensiv. Bei großen Dateien  geht Java aber
auch  andere Implementierung wie in Delphi schnell
in die Knie. SAX hingegen hat nur das momentanne 
Kontenpaar + evt den PCDATA Block im Speicher.
Aber das hatte ich ja schon geschrieben.

Bis denne Huck


----------

