Allgemein: XML-File erstellen

gring0

Mitglied
Hallo,

mein Ziel ist es bestimmte Daten (Auftrag + Positionen) die ich aus einer Datenbank lese in ein XML-File zu schreiben.

Da diese Anforderung sicher nicht die erste dieser Art ist, dachte ich mir es gibt sicherlich ein paar bestimmte Klassen die mir diese Arbeit quasi abnehmen.

Nach meiner ersten Recherche über Google hab ich aber bald erkannt, dass das ganze Thema viel zu umfangreich ist und es viel mehr als blos "ein paar" Klassen dazu gibt.

Was ich jetzt benötigen würde ist ein kleiner Schubs in die richtige Richtung.
Wie gesagt ist mein Ziel einfach eine XML-Datei in ein bestimmtes Verzeichnis mit ein paar Daten auszugeben und das wars. Was ist hierfür die gängige Methode, welche Packages benötige ich etc.

Vielen Dank für eure Hilfe!

Gruß,
ging0
 
Hallo,

Schau mal hier:
Java:
/**
 * 
 */
package de.tutorials;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Order {
    Long id;
    Date date;
    String customer;
    List<LineItem> items;

    public Order() {
        this("NO_CUSTOMER");
    }

    public Order(String customer) {
        this(customer, new Date());
    }

    /**
     * @param customer
     * @param date
     */
    public Order(String customer, Date date) {
        super();
        this.customer = customer;
        this.date = date;
        this.items = new ArrayList<LineItem>();
    }

    public Order add(LineItem item) {
        getItems().add(item);
        return this;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getCustomer() {
        return customer;
    }

    public void setCustomer(String customer) {
        this.customer = customer;
    }

    public List<LineItem> getItems() {
        return items;
    }
    
    

    public void setItems(List<LineItem> items) {
        this.items = items;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((customer == null) ? 0 : customer.hashCode());
        result = prime * result + ((date == null) ? 0 : date.hashCode());
        result = prime * result + ((items == null) ? 0 : items.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        final Order other = (Order) obj;
        if (customer == null) {
            if (other.customer != null)
                return false;
        } else if (!customer.equals(other.customer))
            return false;
        if (date == null) {
            if (other.date != null)
                return false;
        } else if (!date.equals(other.date))
            return false;
        if (items == null) {
            if (other.items != null)
                return false;
        } else if (!items.equals(other.items))
            return false;
        return true;
    }

}

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

public class LineItem {
    Long id;
    String name;
    String description;
    double quantity;
    double price;

    public LineItem(){
        
    }
    
    /**
     * @param name
     * @param quantity
     * @param price
     */
    public LineItem(String name, double quantity, double price) {
        super();
        this.name = name;
        this.quantity = quantity;
        this.price = price;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public double getQuantity() {
        return quantity;
    }

    public void setQuantity(double quantity) {
        this.quantity = quantity;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((description == null) ? 0 : description.hashCode());
        result = prime * result
                + ((name == null) ? 0 : name.hashCode());
        long temp;
        temp = Double.doubleToLongBits(price);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(quantity);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        final LineItem other = (LineItem) obj;
        if (description == null) {
            if (other.description != null)
                return false;
        } else if (!description.equals(other.description))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (Double.doubleToLongBits(price) != Double
                .doubleToLongBits(other.price))
            return false;
        if (Double.doubleToLongBits(quantity) != Double
                .doubleToLongBits(other.quantity))
            return false;
        return true;
    }

}

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

import java.beans.XMLEncoder;
import java.io.FileOutputStream;

/**
 * @author Thomas.Darimont
 * 
 */
public class XMLOutputExample {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception{
        Order order = new Order("Thomas Darimont");
        order.add(new LineItem("Salami Pizza", 3.0, 4.99)).add(
                new LineItem("Calzone", 5.0, 2.99)).add(
                new LineItem("Ginger Ale", 10.0, 1.99));
        
        XMLEncoder encoder = new XMLEncoder(new FileOutputStream("c:/order.xml"));
        encoder.writeObject(order);
        encoder.close();

    }
}

Ausgabe_ order.xml:
XML:
<?xml version="1.0" encoding="UTF-8"?> 
<java version="1.6.0" class="java.beans.XMLDecoder"> 
 <object class="de.tutorials.Order"> 
  <void property="customer"> 
   <string>Thomas Darimont</string> 
  </void> 
  <void property="date"> 
   <object class="java.util.Date"> 
    <long>1174227012500</long> 
   </object> 
  </void> 
  <void property="items"> 
   <void method="add"> 
    <object class="de.tutorials.LineItem"> 
     <void property="name"> 
      <string>Salami Pizza</string> 
     </void> 
     <void property="price"> 
      <double>4.99</double> 
     </void> 
     <void property="quantity"> 
      <double>3.0</double> 
     </void> 
    </object> 
   </void> 
   <void method="add"> 
    <object class="de.tutorials.LineItem"> 
     <void property="name"> 
      <string>Calzone</string> 
     </void> 
     <void property="price"> 
      <double>2.99</double> 
     </void> 
     <void property="quantity"> 
      <double>5.0</double> 
     </void> 
    </object> 
   </void> 
   <void method="add"> 
    <object class="de.tutorials.LineItem"> 
     <void property="name"> 
      <string>Ginger Ale</string> 
     </void> 
     <void property="price"> 
      <double>1.99</double> 
     </void> 
     <void property="quantity"> 
      <double>10.0</double> 
     </void> 
    </object> 
   </void> 
  </void> 
 </object> 
</java>

Eine weitere Variante wäre es dann das XML Dokument selbst im Speicher zusammenzubauen...
Das würde dann ungefähr so aussehen:
Java:
/**
 * 
 */
package de.tutorials;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * @author Thomas.Darimont
 * 
 */
public class XMLOutputExample {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		Order order = new Order("Thomas Darimont");
		order.add(new LineItem("Salami Pizza", 3.0, 4.99)).add(
				new LineItem("Calzone", 5.0, 2.99)).add(
				new LineItem("Ginger Ale", 10.0, 1.99));
		//		
		// XMLEncoder encoder = new XMLEncoder(new
		// FileOutputStream("c:/order.xml"));
		// encoder.writeObject(order);
		// encoder.close();

		Document document = DocumentBuilderFactory.newInstance()
				.newDocumentBuilder().newDocument();
		Element ordersRootElement = document.createElement("orders");
		document.appendChild(ordersRootElement);
		Element orderElement = document.createElement("order");
		ordersRootElement.appendChild(orderElement);
		orderElement.setAttribute("id", String.valueOf(order.getId()));
		orderElement.setAttribute("customer", String.valueOf(order
				.getCustomer()));
		orderElement.setAttribute("date", String.valueOf(order.getDate()));

		TransformerFactory.newInstance().newTransformer().transform(
				new DOMSource(document), new StreamResult("c:/orders.xml"));
	}
}

XML:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><orders><order customer="Thomas Darimont" date="Sun Mar 18 15:36:12 CET 2007" id="null"/></orders>

Etwas eleganter gehts dann mit einer XML Binding Technologie wie beispielsweise JAXB:
http://www.tutorials.de/forum/java/263489-jaxb-tutorial.html

...oder Castor, XMLBeans ( http://www.tutorials.de/forum/java/188797-aus-xml-schema-passende-java-klassen-generieren.html )
XStream ist auch einen Versuch Wert:
http://xstream.codehaus.org/

Gruß Tom
 
Zuletzt bearbeitet von einem Moderator:
Hallo Thomas,

zuerst mal vielen Dank für die Antwort.

Bei der ersten Variante stört mich, dass sich das XML viel zu sehr aufbläst mit (für mich) unnötigen Informationen.

Die zweite Variante kommt aufgrund der Anzahl meiner Attribute (60-70) auch nicht in Frage.

Soweit ich die Binding-Technologie verstanden habe, ist diese erst ab J2SE 5.0 möglich da diese über Annotationen arbeitet (?). Jedenfalls arbeiten wir noch mit J2SE 1.4...

An XMLBeans und XStream hab ich derzeit noch nichts zum Aussetzen gefunden, werd mich wohl für eins von den beiden entscheiden. XStream sieht wirklich simple aus, denke da kann man am wenigsten falsch machen :)

Gruß + danke,
gring0
 
Hallo,

XStream sieht wirklich simple aus, denke da kann man am wenigsten falsch machen :)

Jepp, unter den Voraussetzungen ist das wohl am einfachsten.
Java:
/**
 * 
 */
package de.tutorials;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * @author Thomas.Darimont
 * 
 */
public class XMLOutputExample {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        Order order = new Order("Thomas Darimont");
        order.add(new LineItem("Salami Pizza", 3.0, 4.99)).add(
                new LineItem("Calzone", 5.0, 2.99)).add(
                new LineItem("Ginger Ale", 10.0, 1.99));

        XStream xstream = new XStream(new DomDriver());
        xstream.alias("order", Order.class);
        xstream.alias("lineitem", LineItem.class);

        String xml = xstream.toXML(order);
        System.out.println(xml);

    }
}

Ausgabe:
XML:
<order>
  <date>2007-03-18 17:17:33.656 CET</date>
  <customer>Thomas Darimont</customer>
  <items>
    <lineitem>
      <name>Salami Pizza</name>
      <quantity>3.0</quantity>
      <price>4.99</price>
    </lineitem>
    <lineitem>
      <name>Calzone</name>
      <quantity>5.0</quantity>
      <price>2.99</price>
    </lineitem>
    <lineitem>
      <name>Ginger Ale</name>
      <quantity>10.0</quantity>
      <price>1.99</price>
    </lineitem>
  </items>
</order>

Gruß Tom
 
Zuletzt bearbeitet von einem Moderator:
Hallo!

Hatte ein ähnliches Problem und habe es dank dem ersten Beispiel auch geschafft mein xml file zu erstellen (Also mit Benutzung des java.beans.XMLDecoder bzw. Encoder).
Danke Thomas!

Jetzt will ich das Programm aber mit Hilfe von Ant ausführen und bekomme dann immer eine class not found exception. In der Zeile

encoder.writeObject(order);

wird die Klasse von der 'order' eine Instanz ist plötzlich nicht mehr gefunden.
Hat vielleicht jemand Erfahrungen mit Ant und kann mir sagen worans liegt?

Grüße! tori
 
Zurück