Hallo an alle.
Ich verzweifle gerade an einer XML Reader class. Die class soll (wär jz nicht zu erwarten gewesen) ein xml file auslesen. Die Klasse soll aber als eine Art Helper definiert sein.
Meine Aufgabenstellung lautet:
Lese alle elements und speichere sie wie folgt ab:
[XML]<root>
<product>
<id>3</id>
<lieferadresse>
<name>bla</name>
</lieferadresse>
<rechnungsadresse>
<name>bla2</name>
</rechnungsadresse>
</product>
<prodcut>
...
</product>
</root>[/XML]
Das ist mal eine vereinfachte Variante von meiner xml Datei. Ich soll nun für jedes product eine HashMap erzeugen in der ich alles reinspeichere. Die Lieferadresse und die Rechnungsadresse sind eigene complexTypes die ich wiederrum in eine HashMap speichern soll also in der ersten HashMap soll ich als key "lieferadresse" rein haun und als value soll ich eine HashMap zurück bekommen wo dann dessen Daten drinstehen.
Attribute sollen auch gesichert werden ...
Ich habs mal (ziemlich ziemlich ziemlich hässlich) soweit:
Wie ihr seht ist dass alles zusammen sehr schlecht programmiert (wollte es irgendwie quick&dirty lösen) vorallem die wichtigste Methode die getListOfHashMaps(). Eigentlich funktioniert das meiste irgendwie, bis auf die complexTypes, da ich keine Abfrage drin hab ob das element komplex ist und somit überschreibe ich die gleichen tagNames von der Lieferadresse und von der Rechnungsadresse ...
So, kann mir jemand helfen da die complexTypes noch irgendwie rein zu bekommen oder kann mir jemand einen guten fertigen Helper empfehlen den ich verwenden könnte?
Ich muss dieses Chaos irgendwie loswerden ^^
Dank im vorraus
€: update auf 1.6
Ich verzweifle gerade an einer XML Reader class. Die class soll (wär jz nicht zu erwarten gewesen) ein xml file auslesen. Die Klasse soll aber als eine Art Helper definiert sein.
Meine Aufgabenstellung lautet:
Lese alle elements und speichere sie wie folgt ab:
[XML]<root>
<product>
<id>3</id>
<lieferadresse>
<name>bla</name>
</lieferadresse>
<rechnungsadresse>
<name>bla2</name>
</rechnungsadresse>
</product>
<prodcut>
...
</product>
</root>[/XML]
Das ist mal eine vereinfachte Variante von meiner xml Datei. Ich soll nun für jedes product eine HashMap erzeugen in der ich alles reinspeichere. Die Lieferadresse und die Rechnungsadresse sind eigene complexTypes die ich wiederrum in eine HashMap speichern soll also in der ersten HashMap soll ich als key "lieferadresse" rein haun und als value soll ich eine HashMap zurück bekommen wo dann dessen Daten drinstehen.
Attribute sollen auch gesichert werden ...
Ich habs mal (ziemlich ziemlich ziemlich hässlich) soweit:
Java:
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import org.w3c.dom.*;
import org.xml.sax.*;
import test.StringFunctions;
import javax.xml.parsers.*;
/**
* Diese Klasse liest ein .xml File aus und gibt die gelesenen Elements entweder <br>
* mit der Methode getList(), getHashMap() oder getListOfHashMaps() zurück. <br>
*
* Best Practice: getListOfHashMaps()
* @author schmid.k
*/
public class ParseXMLFile {
private ArrayList<String> list = new ArrayList<String>();
private static final String trennzeichen = "#";
private static String startNode;
private int count = 0;
/**
* Liefert das verwendete Trennzeichen zurück welches bei den Methoden getList(), getHashMap()
* und getListOfHasMaps() verwendet wurde.
* @return String Trennzeichen
*/
public static String getTrennzeichen() {
return trennzeichen;
}
/**
* Liefert die Anzahl an eingelesenen startNodes zurück. <br>
* @return anzahl
*/
public int getAnzahl() {
return count;
}
private void add(String value) {
list.add(value);
}
/**
* Die Datensätze werden wie folgt geliefert: <br>
* nodeName/trennzeichen/nodeValue/trennzeichen/attributeName/trennzeichen/attributeValue...
* @return Erhalt der Datensätze der .xml Datei in einer ArrayList<br>
*/
public ArrayList<String> getList() {
return list;
}
/**
* <b>ACHTUNG: Nur anwendbar wenn jeder key einzigartig ist.</b>
* @return Erhalt der Datensätze der .xml Datei in einer HashMap.
*/
public HashMap<String,String> getHashMap() {
HashMap<String,String> hm = new HashMap<String,String>();
String[] datensatz;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < list.size(); i++){
datensatz = list.get(i).toString().split(trennzeichen);
if (datensatz.length == 1)
hm.put(datensatz[0], "");
if (datensatz.length == 2) {
hm.put(datensatz[0], datensatz[1]);
} else {
for (int j = 1; j < datensatz.length; j++) {
sb.append(datensatz[j]);
sb.append(trennzeichen);
}
hm.put(datensatz[0], sb.toString());
}
}
return hm;
}
/**
* Gibt alle Header Informationen in einer ArrayList zurück. <br>
* nodeName/trennzeichen/nodeValue/trennzeichen/attributeName/trennzeichen/attributeValue...
* @return Erhalt der Headerdaten der .xml Datei in einer ArrayList.
*/
public ArrayList<String> getHeader() {
ArrayList<String> header = new ArrayList<String>();
boolean check = true;
for (int i = 0; i<list.size(); i++) {
String line = list.get(i).toString().trim();
if(!line.split(trennzeichen)[0].equals(startNode) && check) {
header.add(line);
}
else {
check = false;
}
}
return header;
}
/**
* Gibt alle Header Informationen in einer HashMap zurück.<br>
* key = nodeName<br>
* value = nodeValue/trennzeichen/attributeName/trennzeichen/attributeValue...
* @return Erhalt der Headerdaten der .xml Datei in einer HashMap.
*/
public HashMap<String, String> getHeaderAsHashMap() {
ArrayList<String> header = getHeader();
HashMap<String,String> map = new HashMap<String,String>();
for (int i = 0; i<header.size(); i++) {
String line = header.get(i).toString();
if (line.contains(trennzeichen)) {
String[] lines = line.split(trennzeichen);
if (lines.length>2) {
map.put(lines[0], line.substring(lines[0].length()+1));
} else {
map.put(lines[0], lines[1]);
}
}
}
return map;
}
/**
* <br>
* <b>getListOfHashMaps()</b><br><br>
* Erhalt der Datensätze der .xml Datei in einer Liste von HashMaps.<br>
* Diese Methode wird angewand falls in der .xml Datei gleiche keys mehrfach vorkommen. <br><br>
* Der Aufbau verhält sich wiefolgt:<br>
* <b>key</b> = nodeName<br>
* <b>value</b> = nodeValue<br><br>
* Falls Attribute im Node vorhanden sind werden diese dem nodeValue angehängt:<br>
* nodeValue/trennzeichen/attributeName/trennzeichen/attributeValue...<br><br>
* Falls ein Node keinen Value hat, jedoch Attribute werden durch den key sofort die
* Attribute aufgerufen:<br>
* <b>key</b> = nodeName<br>
* <b>value</b> = attributeName/trennzeichen/attributeValue...<br>
* @return ArrayList von HashMaps <br>
*/
public ArrayList<HashMap<String,String>> getListOfHashMaps() {
ArrayList<String> xmlList = getList();
ArrayList<HashMap<String,String>> hashlist = new ArrayList<HashMap<String,String>>();
String key;
String oldKey = "";
String value;
String oldValue = "";
StringBuffer sb = new StringBuffer();
boolean check = false;
boolean checkAttribute = true;
HashMap<String,String> map = new HashMap<String,String>();
// for-Schleife bis size()-1 weil hardcoded ein letzter startNode angehängt wurde
// um eine NullPointerException der letzen if-Abfrage vorzubeugen.
for (int i = 0; i < xmlList.size() - 1; i++){
String[] datensatz = xmlList.get(i).toString().split(trennzeichen);
key = datensatz[0];
// Abfrage um header Daten zu exludieren
if (key.equals(startNode) || check){
check = true;
if (datensatz.length == 2){
value = StringFunctions.convertNullString(datensatz[1]);
}else{
// Wenn datensatz > 1, dann sind Attribute angehängt
if (datensatz.length > 1){
for (int j = 1; j < datensatz.length; j++){
// Abfrage um Attribute mit gleichem key an den alten key anzuhängen
if (oldKey.equals(key) && checkAttribute) {
checkAttribute = false;
oldValue = StringFunctions.convertNullString(map.get(oldKey)).toString().trim();
sb.append(oldValue);
sb.append(trennzeichen);
}
sb.append(datensatz[j]);
// Wenn die Datensatzlänge dem nächsten Iterator entspricht wird kein Trennzeichen angefügt,
// da es sich um den letzten AttributeValue handelt.
if ((j+1) != datensatz.length){
sb.append(trennzeichen);
}
}
// StringBuffer wird als value gespeichert und ...
value = sb.toString();
// ... neu initialisiert.
sb = new StringBuffer();
}else{
value = "";
}
}
if (!value.isEmpty() || !value.equals("")){
if (!key.equals(startNode)){
map.put(key, value);
oldKey = key;
oldValue = "";
checkAttribute = true;
}
// Wenn der nächste iterierte Datensatz dem startNode entspricht, wird die map der list hinzugefügt.
if ((xmlList.get(i + 1).toString().split(trennzeichen)[0]).equals(startNode)){
hashlist.add(map);
map = new HashMap<String,String>();
}
}
}
}
return hashlist;
}
/**
* Datensätze der .xml Datei werden gespeichert. Zum Erhalt dieser entweder getHashMap, getList oder
* (vorzugsweise) getListOfHashMaps aufrufen.
* @param verzeichnis
* @param fileName
* @param firstNode
*/
public ParseXMLFile(String verzeichnis, String fileName, String firstNode) {
ParseXMLFile.startNode = firstNode;
Document doc = parseFile(verzeichnis + fileName);
Node root = doc.getDocumentElement();
getElements(root, firstNode);
// add für getListOfHashMaps
add(firstNode + trennzeichen + " ");
}
/**
* Datensätze der .xml Datei werden gespeichert. Zum Erhalt dieser entweder getHashMap, getList oder
* (vorzugsweise) getListOfHashMaps aufrufen.
* @param file
* @param firstNode
*/
public ParseXMLFile(File f, String firstNode) {
this(f.getPath(), f.getName(), firstNode);
}
private 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 "";
}
//Rekursive Methode zum erhalt aller Nodes aus der .xml Datei
private void getElements(Node node, String firstNode) {
StringBuffer sb = new StringBuffer();
String nodeName = node.getNodeName().trim();
if (nodeName.equals(firstNode)){
add(firstNode + trennzeichen);
count++;
}else{
String nodeValue = getElementValue(node).trim();
if (!nodeValue.equals("")){
sb.append(nodeName + trennzeichen + nodeValue);
}else{
sb.append(nodeName);
}
NamedNodeMap attributes = node.getAttributes();
for (int j = 0; j < attributes.getLength(); j++){
Node attribute = attributes.item(j);
// attributes adden
if (!StringFunctions.convertNullString(attribute.getNodeValue()).equals("")){
sb.append(trennzeichen);
sb.append(attribute.getNodeName());
sb.append(trennzeichen);
sb.append(attribute.getNodeValue());
}
}
add(sb.toString());
//sb = new StringBuffer();
}
// Rekursion: Schreiben der Childs
NodeList children = node.getChildNodes();
for (int j = 0; j < children.getLength(); j++){
Node child = children.item(j);
if (child.getNodeType() == Node.ELEMENT_NODE){
getElements(child, firstNode);
}
}
}
private Document parseFile(String 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("Wrong XML file structure: " + e.getMessage());
return null;
}catch (IOException e){
System.out.println("Could not read source file: " + e.getMessage());
}
return doc;
}
}
Wie ihr seht ist dass alles zusammen sehr schlecht programmiert (wollte es irgendwie quick&dirty lösen) vorallem die wichtigste Methode die getListOfHashMaps(). Eigentlich funktioniert das meiste irgendwie, bis auf die complexTypes, da ich keine Abfrage drin hab ob das element komplex ist und somit überschreibe ich die gleichen tagNames von der Lieferadresse und von der Rechnungsadresse ...
So, kann mir jemand helfen da die complexTypes noch irgendwie rein zu bekommen oder kann mir jemand einen guten fertigen Helper empfehlen den ich verwenden könnte?
Ich muss dieses Chaos irgendwie loswerden ^^
Dank im vorraus
€: update auf 1.6
Zuletzt bearbeitet: