XML einlesen gleichnamige Elemente

leonbrachwitz

Neues Mitglied
Moin Moin!
ich habe ein Problem. Ich versuche die .xml der Europäischen Zentralbank einzulesen. Der Aufbau ist folgendermaßen (von mir gekürzt):
Code:
<?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="2018-08-06">
           <Cube currency="USD" rate="1.1543" />
           <Cube currency="JPY" rate="128.68" />
           <Cube currency="BGN" rate="1.9558" />
       </Cube>
       <Cube time="2018-08-03">
           <Cube currency="USD" rate="1.1588" />
           <Cube currency="JPY" rate="129.3" />
           <Cube currency="BGN" rate="1.9558" />
       </Cube>
   </Cube>
</gesmes:Envelope>

Ich benötige nur die Cube Elemente, welche einen Währungskürzel und den Tageskurs enthalten. Mein Code sieht folgendermaßen aus:
Bei jedem Cube-Element wird ein Objekt Waehrung erstellt. Bei jedem schließenden Cube-Tag, wird das Objekt in eine Liste gepackt. Das Problem: Die letzte Währung (<Cube currency="BGN" rate="1.9558" />) hängt 3 mal in meiner Liste, da ja bei jedem schlißenden Tag das Objekt angehangen wird.
Meine Frage: Wie kann ich das umgehen? Ich möchte jede Währung nur einmal in meiner Liste haben, also in diesem Fall 6stk.

Hier noch der Code:
Code:
public List<Waehrung> liesXmlEin(String xml) throws XMLStreamException
    {
        if (xml == "")
        {
            throw new IllegalArgumentException();
        }
        else
        {
            InputStream inputStream = new ByteArrayInputStream(xml.getBytes());
            XMLInputFactory factory = XMLInputFactory.newInstance();
            XMLEventReader eventReader = factory.createXMLEventReader(inputStream);

            List<Waehrung> waehrungen = new ArrayList<>();
            Waehrung waehrung = null;
            boolean gueltigeWaehrung = false;

            while (eventReader.hasNext())
            {
                XMLEvent xmlEvent = eventReader.nextEvent();

                if (xmlEvent.isStartElement())
                {
                    StartElement startElement = xmlEvent.asStartElement();

                    if ("Cube".equalsIgnoreCase(startElement.getName().getLocalPart()))
                    {
                        waehrung = new Waehrung();
                        gueltigeWaehrung = false;
                    }

                    Iterator<Attribute> iterator = startElement.getAttributes();

                    while (iterator.hasNext())
                    {
                        Attribute attribute = iterator.next();
                        QName name = attribute.getName();

                        if ("currency".equalsIgnoreCase(name.getLocalPart()))
                        {
                            gueltigeWaehrung = true;
                            waehrung.setWaehrungskuerzel((String.valueOf(attribute.getValue())));
                        }

                        if ("rate".equalsIgnoreCase(name.getLocalPart()))
                        {
                            waehrung.setTageskurs(((new BigDecimal(String.valueOf(attribute.getValue())))));
                        }
                    }

                }
                if (xmlEvent.isEndElement())
                {
                    EndElement endElement = xmlEvent.asEndElement();

                    if ("Cube".equalsIgnoreCase(endElement.getName().getLocalPart())
                            && (gueltigeWaehrung == true))
                    {
                        waehrungen.add(waehrung);
                    }
                }
            }

            return waehrungen;
        }

    }
 

looparda

Top Contributor
Du brauchst das EndElement nicht. Sobald du auf ein Cube-Element stößt liest du die Attribute und im Anschluss hast du doch dein Währungsobjekt fertig bestückt, um es in die Liste zu packen.
Die einzige Ausnahme ist das äußere cube-Element, welches cube-Elemente enthält. Hier kannst du ein Flag setzen, sobald du das erste cube-Element passiert hast. Nachdem das Flag gesetzt wurde kannst du sicher sein, dass alle folgenden Cube-Elemente die Attribute enthalten, die du auslesen willst.
Java:
Iterator<Attribute> iterator = startElement.getAttributes();
while (iterator.hasNext()) {...}
// hier hast du bereits alle Informationen um dein Währungsobjekt in die Liste zu packen
 

Flown

Administrator
Mitarbeiter
Also wenn ich etwas in einem XML suche, dann nur mit XPath:
Java:
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
    "<gesmes:Envelope\n" +
    "   xmlns:gesmes=\"http://www.gesmes.org/xml/2002-08-01\"\n" +
    "   xmlns=\"http://www.ecb.int/vocabulary/2002-08-01/eurofxref\">\n" +
    "   <gesmes:subject>Reference rates</gesmes:subject>\n" +
    "   <gesmes:Sender>\n" +
    "       <gesmes:name>European Central Bank</gesmes:name>\n" +
    "   </gesmes:Sender>\n" +
    "   <Cube>\n" +
    "       <Cube time=\"2018-08-06\">\n" +
    "           <Cube currency=\"USD\" rate=\"1.1543\" />\n" +
    "           <Cube currency=\"JPY\" rate=\"128.68\" />\n" +
    "           <Cube currency=\"BGN\" rate=\"1.9558\" />\n" +
    "       </Cube>\n" +
    "       <Cube time=\"2018-08-03\">\n" +
    "           <Cube currency=\"USD\" rate=\"1.1588\" />\n" +
    "           <Cube currency=\"JPY\" rate=\"129.3\" />\n" +
    "           <Cube currency=\"BGN\" rate=\"1.9558\" />\n" +
    "       </Cube>\n" +
    "   </Cube>\n" +
    "</gesmes:Envelope>";

try {
  DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
  DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
  Document document = documentBuilder.parse(new InputSource(new StringReader(xml)));

  XPathFactory xPathFactory = XPathFactory.newInstance();
  XPath xPath = xPathFactory.newXPath();
  
  NodeList currencies = (NodeList) xPath.evaluate("//Cube[@currency and @rate]", document, XPathConstants.NODESET);
  for (int i = 0; i < currencies.getLength(); i++) {
    Node currency = currencies.item(i);
    System.out.println(xPath.evaluate("./@currency", currency) + ": " + xPath.evaluate("./@rate", currency));
  }
} catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException e) {
  e.printStackTrace();
}
Output:
Code:
USD: 1.1543
JPY: 128.68
BGN: 1.9558
USD: 1.1588
JPY: 129.3
BGN: 1.9558
 

looparda

Top Contributor
Aber allgemein scheint mir die Library nicht passend zu sein, da du immer nur Zugriff auf das aktuelle Element hast und keine Funktionen wie getParent und getChildren, um hierarchisch parsen zu können.
Beispiel mit jdom2 und durchhangeln bis zu den inneren Cubes:
Java:
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class XMLRead {

    public static void main(String[] args) throws IOException {
        new XMLRead().run();
    }

    private void run() throws IOException {
        File file = new File(getClass().getResource("waehrung.xml").getFile());
        final List<Waehrung> waehrungen = liesXmlEin(file);
        for ( Waehrung w : waehrungen) {
            System.out.println(w.getWaehrungskuerzel() + ":" + w.getTageskurs());
        }

    }

    public List<Waehrung> liesXmlEin(File xmlFile)
    {
        List<Waehrung> waehrungen = new ArrayList<>();

        try {
            SAXBuilder saxBuilder = new SAXBuilder();
            Document document = saxBuilder.build(xmlFile);
            Element root = document.getRootElement();
            //TODO: besser getChild(cname, namspace)
            final Element cubeContainer = root.getChildren().stream().filter(c -> c.getName().equals("Cube")).findFirst().orElseThrow(IllegalStateException::new);
            final List<Element> cubesWithDate = cubeContainer.getChildren();
            final List<Element> cubesWithData = cubesWithDate.stream().map(c -> c.getChildren()).flatMap(c -> c.stream()).collect(Collectors.toList());
            cubesWithData.stream().forEach(c -> waehrungen.add( new Waehrung(c.getAttribute("currency").getValue(), new BigDecimal(c.getAttribute("rate").getValue()))));
        } catch(JDOMException e) {
            e.printStackTrace();
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }

        return waehrungen;
    }
}
Code:
USD:1.1543
JPY:128.68
BGN:1.9558
USD:1.1588
JPY:129.3
BGN:1.9558
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
iman XML Attribute mit JAVA einlesen mit Spring Batch XML & JSON 0
J Object in JSON Datei einlesen und als neues Object erzeugen (in ein Object Array) XML & JSON 29
I Mit Hibernate eine XML-Datei in eine Tabellenspalte einlesen. XML & JSON 1
T HTML mit Hilfe Jsoup einlesen XML & JSON 11
R xlsx-Datei mit Apache POI einlesen XML & JSON 18
S CSV Datei einlesen und XML Ausgeben XML & JSON 2
W XML einlesen und Attribute auslesen XML & JSON 1
M XML Werte einlesen aber wie am besten weiterverarbeiten? XML & JSON 13
L XML nur ein Element einlesen XML & JSON 2
L Jackson JSON: Probleme beim einlesen XML & JSON 1
S XML in JTable Einlesen XML & JSON 3
B XML analysieren und einlesen XML & JSON 26
Z XML Datei mit JDOM einlesen und verarbeiten XML & JSON 6
Ollek XML Einlesen - Welche API ist die richtige? XML & JSON 14
X XML einlesen XML & JSON 6
C JAXB: XML-Elemente einlesen und als XML-Attribute ausgeben XML & JSON 7
jstei001 .xsd File wärend der Laufzeit einlesen und XMl rausschreiben XML & JSON 5
J XML mit russischem Inhalt einlesen XML & JSON 4
D XML Einlesen mit JaxB XML & JSON 4
K Einlesen eines Parameters aus HTML-Datei XML & JSON 4
D Wie XML Datei einlesen und HTML entities übernehmen? XML & JSON 3
B Validierung nur beim einlesen oder auch beim schreiben? XML & JSON 4
B SAX-Parser - Dokumente einlesen und in einer Map ablegen XML & JSON 2
N xsd pattern in java einlesen XML & JSON 6
F Einlesen von JDBC connection in Java von XML XML & JSON 4
J wert IN einem tag einlesen/schreiben XML & JSON 4
F XML erzeugen aus JTree und wieder einlesen... XML & JSON 6
N JDOM: XML einlesen XML & JSON 4
F XML mit DOM einlesen- Teile in Arraylist speichern XML & JSON 4
S XML einlesen XML & JSON 18
F XML Datei in Java einlesen XML & JSON 4
H XMI über EMF / UML2 einlesen XML & JSON 7
S XML einlesen, analysieren, bearbeiten & als Textdatei ausgeben XML & JSON 1
E XML Datei einlesen und Elemente in der Console ausgeben XML & JSON 6
H xml-Datei mit Attributen einlesen XML & JSON 3
C xml "zeilenweise" einlesen XML & JSON 6
B XML einlesen und in Datenbank schreiben XML & JSON 1
S XML-Schema einlesen um parsen zu erleichtern? XML & JSON 2
L Element einlesen <Telefon name="Karl">134313 XML & JSON 2
G XML Tag beim Einlesen manipulieren XML & JSON 2
J XML-Datei ein Array einlesen XML & JSON 10
P Große XML Datei mittels JDOM bearbeiten / einlesen XML & JSON 6
G Simples XML File einlesen mit JDom. Prefix not bound ? XML & JSON 2
M Liste in Baumstruktur einlesen XML & JSON 4
D nicht (ganz) valiedes XML einlesen! XML & JSON 19
S Einlesen einer xml Datei XML & JSON 4
S XML Datei einlesen, aber root überspringen XML & JSON 2
M XML einlesen - prüfen ob Element vorhanden XML & JSON 2
M NullPointerException bei Einlesen XML XML & JSON 3
J XML - schreiben und einlesen (Schema) XML & JSON 14
S XML Strings in JAVA einlesen, aber wie? XML & JSON 8
K JDOM SAXBuilder einlesen XML & JSON 6
G Newbe - Frage.XML - Datei einlesen und speichern XML & JSON 2
G xml einlesen und bestimmte Elemente an eine gui_Klasse überg XML & JSON 25
B XML String einlesen XML & JSON 4
M mit JDOM XML-Datei einlesen, die nicht "well-formed&quo XML & JSON 3
T Newbie Frage. CSS Stylesheet einlesen und suchen nach Tags XML & JSON 6
P OutOfMemoryError beim Einlesen einer XML-Datei XML & JSON 7
C Zeile herausfinden in der ein Fehler beim Einlesen entsteht XML & JSON 3
R wie kann ich ein xml file in einen string einlesen? XML & JSON 2
N Objekte via XML speichern und wieder einlesen XML & JSON 12
R POST REQUEST: XmlDocument mit getInputStream einlesen! XML & JSON 6
T Mehrere gleichnamige Unterelemente auslesen XML & JSON 2
J Parent- und Child-Elemente mit gleiche Namen, geht das ? XML & JSON 1
S XML - Bestehende Elemente ändern XML & JSON 1
R Verschachtelung gleichnamiger Elemente XML & JSON 7
D optionale Elemente mit defaultwerten werden in xml miterzeugt XML & JSON 2
A Elemente aus mehreren XML-Dateien zu einem zusammenfügen XML & JSON 5
G JAXB und verschachtelte Elemente? XML & JSON 6
J Anzahl der Elemente in einem XML-Dokument auslesen XML & JSON 7
F Hilfe beim bearbeiten von XML elemente XML & JSON 3
G Wieviele Elemente von TagName, ich brings nicht hin XML & JSON 5
G Leere Elemente verhindern XML & JSON 7
aze JaxB Elemente in LinkedHashSet werden nicht wiededergegeben XML & JSON 3
D Tabs/Einrückungen der XML-Elemente gehen beim Schreiben verloren XML & JSON 5
Z XML auslesen, Elemente daraus entfernen und als neue XML zurückgeben XML & JSON 2
S JTree - Nur Elemente mit Attributen einfügen XML & JSON 2
T Elemente zählen mit JDOM in XML XML & JSON 7
G XML Parser Fehler, zwei gleiche kind-Elemente XML & JSON 7
F Elemente sortieren lassen XML & JSON 2
I Editor, der nur Elemente einfuegt, die nach xsd zulaessig XML & JSON 2
H Elemente eines Node auslesen XML & JSON 2
M XML Elemente mit JDOM durch Text ersetzen XML & JSON 2
P JDom nimmt keine Elemente an. XML & JSON 3
M Elemente mit Prefix via JDOM erstellen XML & JSON 6
J Jdom Elemente lesen XML & JSON 5
P zugriff auf gewuenschte elemente klapp nicht. XML & JSON 3
T Einfach nur die Elemente einer XML Datei auslesen :( XML & JSON 10
T Elemente aus XML-File löschen (JDom) XML & JSON 9
G Xml Elemente in eine Liste abspeichern! XML & JSON 2
G Elemente in XML XML & JSON 4
G brauche Tips, wie ich am besten auf Elemente zugreife XML & JSON 5
D Xml-Datei in JTree anzeigen und Elemente ausblenden XML & JSON 2
S JDOM Elemente suchen XML & JSON 2

Ähnliche Java Themen

Neue Themen


Oben