XML Datei mit JDOM einlesen und verarbeiten

Zombeibraut

Mitglied
Hallo zusammen,

ich arbeite gerade zum ersten Mal mit JDOM und stoße leider auf ein paar Probleme, die mir auch Google und die Suchfunktion nicht lösen konnten.

Ich habe folgende XML Datei pbx.xml:

[XML]<?xml version="1.0" encoding="utf-8"?>
<info>
<user cn="Dritter Third" id="3" e164="103" dn="Dritter T." h323="Dritter T."><device hw="IP110-15-71-cf"/><device hw="Dritter T."/></user>
<user cn="Erster First" id="1" e164="101" dn="Erster F." h323="Erster F."><device hw="IP222-2f-05-08"/><device hw="Erster F."/></user>
<user cn="Fuenfter Fifth" id="5" e164="105" dn="Fuenfter F." h323="Fuenfter F."><device hw="Fuenfter F."/></user>
<user cn="Sechster Sixth" id="6" e164="106" dn="Sechster S." h323="Sechster S."><device hw="Sechster S."/></user>
<user cn="Vierter Fourth" id="4" e164="104" dn="Vierter F." h323="Vierter F."><device hw="IP240-27-07-88"/></user>
<user cn="Zweiter Second" id="2" e164="102" dn="Zweiter S." h323="Zweiter S."><device hw="IP222-2f-00-71"/><device hw="Zweiter S."/></user>
</info>[/XML]

Diese möchte ich gern in mein Javaprogramm einlesen um anschließend die einzelnen User mit ihren Attributen cn, id, e164 usw. weiterzuverarbeiten. Bisher habe ich es immerhin geschafft die komplette Datei einzulesen und mir die einzelnen Elemente (ohne Attribute) anzeigen zu lassen.

Java:
import java.io.File; 
import java.io.IOException; 
import java.util.Iterator;
import java.util.List; 

import org.jdom2.Attribute;
import org.jdom2.Document; 
import org.jdom2.Element; 
import org.jdom2.JDOMException; 
import org.jdom2.input.SAXBuilder; 
import org.jdom2.output.XMLOutputter; 

class JDOMLesen { 

    public static void main(String[] args) { 


        File file = new File("c:\\pbx.xml");

        try { 
            // Das Dokument einlesen
            SAXBuilder builder = new SAXBuilder(); 
            Document doc = builder.build(file); 
            
            XMLOutputter fmt = new XMLOutputter(); 

            // komplettes Dokument ausgeben 
            fmt.output(doc, System.out); 

            // Wurzelelement ausgeben 
            Element root = doc.getRootElement(); 
            System.out.println("\nWurzelelement: " + root); 

            // Wurzelelementnamen ausgeben 
            System.out.println("Rootelement: " + root.getName()); 
            
            Element user = root.getChild("user");
			System.out.println("Kind1: " +root.getChild("user"));
			
			Element device = user.getChild("device");
			System.out.println("Kind2: " + device);

            // Eine Liste aller direkten Kindelemente eines Elementes erstellen 
            List users = root.getChildren("user"); 
            System.out.println("Childelement: " 
                    + ((Element) users.get(0)).getName()); 
            System.out.println(users);          
           
        } catch (JDOMException e) { 
            e.printStackTrace(); 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
    } 
}

Als Ausgabe erhalte ich Folgendes:

Java:
<?xml version="1.0" encoding="UTF-8"?>
<info>
<user cn="Dritter Third" id="3" e164="103" dn="Dritter T." h323="Dritter T."><device hw="IP110-15-71-cf" /><device hw="Dritter T." /></user>
<user cn="Erster First" id="1" e164="101" dn="Erster F." h323="Erster F."><device hw="IP222-2f-05-08" /><device hw="Erster F." /></user>
<user cn="Fuenfter Fifth" id="5" e164="105" dn="Fuenfter F." h323="Fuenfter F."><device hw="Fuenfter F." /></user>
<user cn="Sechster Sixth" id="6" e164="106" dn="Sechster S." h323="Sechster S."><device hw="Sechster S." /></user>
<user cn="Vierter Fourth" id="4" e164="104" dn="Vierter F." h323="Vierter F."><device hw="IP240-27-07-88" /></user>
<user cn="Zweiter Second" id="2" e164="102" dn="Zweiter S." h323="Zweiter S."><device hw="IP222-2f-00-71" /><device hw="Zweiter S." /></user>
</info>

Wurzelelement: [Element: <info/>]
Rootelement: info
Kind1: [Element: <user/>]
Kind2: [Element: <device/>]
Childelement: user
[[Element: <user/>], [Element: <user/>], [Element: <user/>], [Element: <user/>], [Element: <user/>], [Element: <user/>]]

Ich würde mich freuen, wenn mir jemand weiterhelfen kann.
Viele Grüße
 
Zuletzt bearbeitet:
Oh tut mir leid, war vielleicht etwas schwammig formuliert.

Also ich würde gern die einzelnen User Erster, Zweiter usw. so aus der XML einlesen mit allen Attributen, dass ich die entsprechenden Daten so an eine Klasse Benutzer senden und als deren Instanz verwenden kann. Am Schluss möchte ich die Benutzer dann per JDBC an eine Datenbank weiterleiten.

Ist das so überhaupt machbar, wie ich mir das vorstelle, oder gehe ich völlig falsch an die Sache ran?

Viele Grüße

______________________________________________________________________________________

Ich bin noch einen Schritt weiter gekommen und kann mir jetzt die Attribute mit Werten vom ersten User und ersten Device ausgeben lassen. Jetzt bräuchte ich also nur noch Hilfe dabei, wie ich das selbe wie für übrigen User hin bekomme.

Java:
			//Attribute des ersten Users ausgeben
			Attribute name = user.getAttribute("cn");
			String nameName = name.getName();
			String nameValue = name.getValue();
			System.out.println("Name: "+ nameName + ": " + nameValue);
			
			Attribute id = user.getAttribute("id");
			String idName = id.getName();
			String idValue = id.getValue();
			System.out.println("ID: " + idName +": "+ idValue);
			
			Attribute tel = user.getAttribute("e164");
			String teleName = tel.getName();
			String teleValue = tel.getValue();
			System.out.println("Telefonnummer: " + teleName +": "+ teleValue);
			
			Attribute dn = user.getAttribute("dn");
			String dnName = dn.getName();
			String dnValue = dn.getValue();
			System.out.println("Kürzel: " + dnName +": "+ dnValue);
			
			//Second Child ausgeben
			Element device = user.getChild("device");
			System.out.println("Kind2: " + device);
			
			//Attribute des ersten Devices ausgeben
			Attribute hw = device.getAttribute("hw");
			String hwName = hw.getName();
			String hwValue = hw.getValue();
			System.out.println("MAC: " + hwName + ": " + hwValue);

Dabei erhalte ich nun folgende Ausgabe:

Java:
<?xml version="1.0" encoding="UTF-8"?>
<info>
<user cn="Dritter Third" id="3" e164="103" dn="Dritter T." h323="Dritter T."><device hw="IP110-15-71-cf" /><device hw="Dritter T." /></user>
<user cn="Erster First" id="1" e164="101" dn="Erster F." h323="Erster F."><device hw="IP222-2f-05-08" /><device hw="Erster F." /></user>
<user cn="Fuenfter Fifth" id="5" e164="105" dn="Fuenfter F." h323="Fuenfter F."><device hw="Fuenfter F." /></user>
<user cn="Sechster Sixth" id="6" e164="106" dn="Sechster S." h323="Sechster S."><device hw="Sechster S." /></user>
<user cn="Vierter Fourth" id="4" e164="104" dn="Vierter F." h323="Vierter F."><device hw="IP240-27-07-88" /></user>
<user cn="Zweiter Second" id="2" e164="102" dn="Zweiter S." h323="Zweiter S."><device hw="IP222-2f-00-71" /><device hw="Zweiter S." /></user>
</info>

Wurzelelement: [Element: <info/>]
Rootelement: info
Kind1: [Element: <user/>]
Name: cn: Dritter Third
ID: id: 3
Telefonnummer: e164: 103
Kürzel: dn: Dritter T.
Kind2: [Element: <device/>]
MAC: hw: IP110-15-71-cf
Kind3: null
Childelement: user
[[Element: <user/>], [Element: <user/>], [Element: <user/>], [Element: <user/>], [Element: <user/>], [Element: <user/>]]

Hat jemand einer Idee, wie ich das nun für die übrigen Zeilen weiter führen kann?
 
Zuletzt bearbeitet:
Natürlich..jetzt wirds Licht 🙂

Du hast eigentlich schon alles.

Der Code den du gepostet hast fpr die User-Attribute, den einfach in ne Schleife packen:

Java:
   List users = root.getChildren("user"); 
for(int i=0; i<users.size(); i++){
 Element user = (Element) users.get(i);
            //Attribute des ersten Users ausgeben
            Attribute name = user.getAttribute("cn");
            String nameName = name.getName();
            String nameValue = name.getValue();
            System.out.println("Name: "+ nameName + ": " + nameValue);
            
            Attribute id = user.getAttribute("id");
            String idName = id.getName();
            String idValue = id.getValue();
            System.out.println("ID: " + idName +": "+ idValue);
            
            Attribute tel = user.getAttribute("e164");
            String teleName = tel.getName();
            String teleValue = tel.getValue();
            System.out.println("Telefonnummer: " + teleName +": "+ teleValue);
            
            Attribute dn = user.getAttribute("dn");
            String dnName = dn.getName();
            String dnValue = dn.getValue();
            System.out.println("Kürzel: " + dnName +": "+ dnValue);
            
            //Second Child ausgeben
            Element device = user.getChild("device");
            System.out.println("Kind2: " + device);
            
            //Attribute des ersten Devices ausgeben
            Attribute hw = device.getAttribute("hw");
            String hwName = hw.getName();
            String hwValue = hw.getValue();
            System.out.println("MAC: " + hwName + ": " + hwValue);

}
 
Super, vielen Dank!

Jetzt würde ich das gern äquivalent auch für die devices machen:

Java:
			Element user = root.getChild("user");
			List devices = user.getChildren("device");
			for(int j=0; j<devices.size(); j++){
			Element device = (Element) devices.get(j);	
			
			//Attribute des ersten Devices ausgeben
			Attribute hw = device.getAttribute("hw");
			String hwName = hw.getName();
			String hwValue = hw.getValue();
			System.out.println("MAC: " + hwName + ": " + hwValue);
			}

Allerdings bekomme ich so nur die Attribute des ersten device ausgegeben.
Wo liegt mein Fehler?
 
Erst mal ein allgemeiner Tipp. JDOM2 unterstützt Generics. Die solltest Du auch nutzen. Dadurch sparst Du Dir eine Menge Gecaste, z.B. hier:
[JAVA=43]
// Eine Liste aller direkten Kindelemente eines Elementes erstellen
List users = root.getChildren("user"); //<-- Nicht so gut, weil ohne Generics
System.out.println("Childelement: "
+ ((Element) users.get(0)).getName()); // <-- Deswegen ist hier ein Cast nötig

// Besser so:
List<Element> users = root.getChildren("user");
System.out.println("Childelement: " + users.get(0).getName());
[/code]
Für die Iteration (.z.B. über die users) kannst Du anstatt der for-Schleife mit index auch die etwas schönere for-each-Schleife nehmen:
Java:
for(Element user : users ) {
  // den ganzen user-Kram ausgeben
}
Zombeibraut hat gesagt.:
Allerdings bekomme ich so nur die Attribute des ersten device ausgegeben.
Wo liegt mein Fehler?
Abgesehen von dem Fehlen der Generics und dem Verwenden eines Index statt foreach sieht der Code gut aus. Kann es sein, dass Du den Code unglücklicherweise mit einem User-Element getestet hast, das nur ein device enthält (ids 4,5,6)?
 
Danke für den Tipp, das werde ich gleich mal ausprobieren!

Ja, da wird der Fehler liegen. Dann nehme ich die Abfrage nach den Devices am besten einfach auch mit in die Schleife um alle abzugreifen, oder?

Danke für die schnelle Hilfe 🙂
 

Zurück
Oben