Hi,
es gibt heutzutage in Java verschiedene Libraries, die
- aus dem XML-Schema,
- einer mapping Datei,
- einem Java-Bean
- einem einkommenden xml file
prima mit sehr wenig Code xml Dateien in Java Objekt Strukturen umwandeln können.
(JAXB oder
http://xmlbeans.apache.org/ ).
Ich habe leider noch keine praktische Erfahrung damit. Und die Schemastruktur der täglichen Wechselkurse der EZB sieht ein bischen merkwürdig aus, um damit unter dem normalen Zeitdruck jetzt anzufangen.
<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
<gesmes:subject>Reference rates</gesmes:subject>
<gesmes:Sender>
<gesmes:name>European Central Bank</gesmes:name>
</gesmes:Sender>
<Cube>
<Cube time='2006-02-13'>
<Cube currency='USD' rate='1.1888'/>
<Cube currency='JPY' rate='140.35'/>
[...stark gekürzt... Axel]
</Cube>
</Cube>
</gesmes:Envelope>
Man kann da natürlich immer mit der DOM-Api ran. Aber das ist vermutlich unnötig und es erzeugt ziemlich chaotischen Code:
Der ist übrigens ziemlich "notes-ähnlich", womit ich nicht sagen will, dass Notes chaotisch ist, sondern einfach, dass xml als Datenbank ziemlich notes-ähnlich ist.
(ich zerleg den Code natürlich noch in mehrere private functions).
InputStream is = null;
try {
if (get.getStatusCode() != 200) {
errMsg = "Die URL ist nicht erreichbar:" + urlEcbDaily
+ ". (http-Statuscode=" + get.getStatusCode();
throw new WebRetrievalException(errMsg);
}
is = get.getResponseBodyAsStream();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// erzeuge Dokument
Document doc = db.parse(is);
// hole alle Nodes mit dem Namen Cube (wie notesDocumentCollection.getAllDocumentsByKey()
NodeList nlCube = doc.getElementsByTagName("Cube");
Date date = null;
ExchangeRate exchRate = null;
// hier kommen die JavaBeans rein
Set exchRates = new HashSet();
for (int i = 0; i < nlCube.getLength(); i++) {
// iteriere über alle Elemente Cube.
Element cubeElement = (Element) nlCube.item(i);
if (cubeElement.getNodeType() == cubeElement.ELEMENT_NODE) {
// hole alle Attribute der node und iteriere über sie.
// im Element <Cube currency='MYR' rate='4.4265'/> sind currency="MYR" und rate="4.4265" die Attribute.
NamedNodeMap cubeAttr = cubeElement.getAttributes();
for (int j = 0; j < cubeAttr.getLength(); j++) {
Node attr = cubeAttr.item(j);
String attrName = attr.getNodeName();
// je nach dem Namen des Attributs mache unterschiedliche Operationen
// (Beans erzeugen, in einen Set (-> sowas wie ein dynamischer Array) tun, etc.
if (attrName.equals("time")) {
String[] dateParts = attr.getNodeValue().split("-");
date = new Date();
date.setYear(Integer.parseInt(dateParts[0]));
date.setMonth(Integer.parseInt(dateParts[1]) - 1);
date.setDate(Integer.parseInt(dateParts[2]));
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
System.out.println("date=" + date);
} else if ((attrName.equals("currency"))
|| (attrName.equals("rate"))) {
if (j == 0) {
exchRate = new ExchangeRate();
exchRates.add(exchRate);
exchRate.setDate(date);
}
if (attrName.equals("currency")) {
exchRate.setCurrencyCode(attr.getNodeValue());
}
else if (attrName.equals("rate")) {
exchRate.setRate(Double.parseDouble(attr
.getNodeValue()));
}
System.out.println(" Attribute: (" + j + ")"
+ attr.getNodeName() + " = "
+ attr.getNodeValue());
}
}
}
}
System.out.println(exchRates);
}
Zur Not geht also die DOM-APi und sie ist ziemlich notes-ähnlich, wie gesagt.
Weiss jemand irgendwelche bessere Ideen.
Und die Struktur des xml files scheint mir echt nicht so richtig koscher zu sein.
Es gibt 2 Namespaces. Und die Cube Elemente sind so merkwürdig geschachtelt.
Keine direkte Frage, aber kann jemand etwas intelligentes posten?
Gruß Axel