XML-Element komplett löschen

Diskutiere XML-Element komplett löschen im XML und Co. Forum; Hallo, in folgender XML-Datei möchte ich beispielsweise das Element "city" mit dem Attribut "name=Aalen" komplett löschen, also inklusive aller...

  1. Wambui
    Wambui Mitglied
    Hallo,

    in folgender XML-Datei möchte ich beispielsweise das Element "city" mit dem Attribut "name=Aalen" komplett löschen, also inklusive aller Kindselemente von "Aalen".

    Code (Text):
    <?xml version="1.0" encoding="UTF-8"?>
    <costcalculator>
      <city name="München">
        <distance>221.357</distance>
        <duration>2.3294444444444444</duration>
        <monthlyticket>547.00</monthlyticket>
        <roundtripticket>114.0</roundtripticket>
        <hotelcosts>0.00</hotelcosts>
        <publictransport>false</publictransport>
      </city>
      <city name="Frankfurt">
        <distance>204.365</distance>
        <duration>2.0494444444444446</duration>
        <monthlyticket>467.00</monthlyticket>
        <roundtripticket>126.00</roundtripticket>
        <hotelcosts>0.00</hotelcosts>
        <publictransport>false</publictransport>
      </city>
      <city name="Köln">
        <distance>367.153</distance>
        <duration>3.4047222222222224</duration>
        <monthlyticket>292.40</monthlyticket>
        <roundtripticket>185.00</roundtripticket>
        <hotelcosts>49.00</hotelcosts>
        <publictransport>false</publictransport>
      </city>
      <city name="Aalen">
        <distance>78.111</distance>
        <duration>0.9852777777777778</duration>
        <monthlyticket>233.30</monthlyticket>
        <roundtripticket>88.56</roundtripticket>
        <hotelcosts>50.00</hotelcosts>
      </city>
     
    Dazu habe ich folgende Java-Klasse erstellt:
    Code (Text):
    package com.example.exercise;


    import java.io.IOException;
    import java.util.Iterator;
    import java.util.List;

    import org.jdom2.Document;
    import org.jdom2.Element;
    import org.jdom2.JDOMException;
    import org.jdom2.input.SAXBuilder;

    public class Remove {

        public static void main(String[] args) {
            String xmlFile = "/home/wambui/Data/City.xml";
            String cityName = "Aalen";
            try {
                SAXBuilder builder = new SAXBuilder();
                Document doc = (Document) builder.build(xmlFile);

                Element costCalculator = doc.getRootElement();
                Iterator<Element> cities = costCalculator.getChildren("city").iterator();
                while (cities.hasNext()) {
                    Element city = (Element) cities.next();
                    if (cityName.equals(city.getAttribute("name").getValue())) {
                        costCalculator.removeContent(city);
                    }
                   
                }
                   
               
            } catch (JDOMException | IOException e) {
                e.printStackTrace();
            }
        }
    }
    Als Fehlermeldung bekomme ich
    Exception in thread "main" java.util.ConcurrentModificationException: The ContentList supporting the FilterList this iterator is processing has been modified by something other than this Iterator.
    at org.jdom2.ContentList$FilterListIterator.checkConcurrent(ContentList.java:1309)
    at org.jdom2.ContentList$FilterListIterator.next(ContentList.java:1357)
    at org.jdom2.ContentList$FilterListIterator.next(ContentList.java:1260)
    at com.linuxmaker.calculator.exercise.Remove.main(Remove.java:25)


    Jetzt bin ich etwas überfragt, wie ich ein XML-Element komplett löschen kann.

    Grüße
    Wambui
     
    Zuletzt bearbeitet: 27. Aug. 2014
  2. Vielleicht helfen dir diese Grundlagen hier weiter: (hier klicken)
  3. Harry Kane
    Harry Kane Bekanntes Mitglied
    Wenn du Elemente aus einer Collection löscht, über die du gerade iterierst, wirst du in den allermeisten Fällen eine ConcurrentModificationException bekommen. Dieses Verhalten wird grundsätzlich beobachtet, nicht nur bei deinem konkreten Fall.
    Um das zu umgehen, könntest du die gefundenen Elemente z. B. in einer ArrayList speichern und nach der Iteration die Elemente in der ArrayList aus dem costCalculator entfernen.
     
  4. Joose
    Joose Super-Moderator Mitarbeiter
    Harry Kane hat zwar recht mit der Beschreibung warum es zum Fehler kommt.
    Auch die mögliche Behebung durch eine extra Liste und dem Löschen danach ist zwar möglich aber unschön.

    Dein Fehler liegt daran das du die Element auf der eigentlichen Liste entfernst. Rufe stattessen die "remove" Methode auf dem Iterator Objekt auf. So entfernst wird das Objekt vom Iterator und der Liste entfernt.
     
  5. Wambui
    Wambui Mitglied
    Erst einmal Danke für die beiden Erklärungen. Wobei mich die von Harry Kane durcheinander gebracht hatte. Denn ich hatte zum Ändern von Inhalten in der XML-Datei folgenden Code geschrieben:
    Code (Text):
    SAXBuilder builder = new SAXBuilder();
                Document doc = (Document) builder.build(xmlFile);

                Element costCalculator = doc.getRootElement();
               
                Iterator<?> cityList = costCalculator.getChildren("city").iterator();
                while (cityList.hasNext()) {
                    Element city = (Element) cityList.next();
                    if (cityName.equals(city.getAttribute("name").getValue())) {
                        Element monthlyTicket = new Element("monthlyticket");
                        monthlyTicket.addContent(varMonthlyTicket);
                        city.removeChild("monthlyticket");
                        city.addContent(monthlyTicket);
                        Element roundTripTicket = new Element("roundtripticket);
                        roundTripTicket.addContent(varRoundTripTicket);
                        city.removeChild("roundtripticket);
                        city.addContent(roundTripTicket);
                        Element hotelCost = new Element("hotelcosts");
                        hotelCost.addContent(varHotel);
                        city.removeChild("hotelcosts");
                        city.addContent(hotelCost);
                        city.removeChild("publictransport");
                        city.addContent(publictransport);
                    }
                   
                }
    Und das funktioniert definitiv, obwohl ich über im selben Moment über eine Collection iteriere.

    Wenn ich jetzt Deinem Ansatz versuche umzusetzen
    Code (Text):

                            Element costCalculator = doc.getRootElement();
                Iterator<Element> cities = costCalculator.getChildren("city").iterator();
                while (cities.hasNext()) {
                    Element city = (Element) cities.next();
                    if (cityName.equals(city.getAttribute("name").getValue())) {
                        cities.remove();
                    }
                   
                }
     
    dann kommt die ConcurrentModificationException tatsächlich nicht mehr. Allerdings wird in der XML-Datei auch nichts entfernt.
    Entferne ich hiermit lediglich aus dem Iterator-Objekt besagten Eintrag? Wie aber bekomme ich ihn auch aus der XML-Datei heraus?
     
  6. Harry Kane
    Harry Kane Bekanntes Mitglied
    In deinem Beispiel, wo du über eine Liste iterierst und gleichzeitig Veränderungen vornimmst, löschst du zwar Informationen aus den Objekten in der Liste, löschst aber nicht die Objekte in der Liste!
    Anders ausgedrückt: Objekte in einer Liste können durchaus verändert werden, während du über die Liste iterierst, aber nicht die Liste selbst.
    Hast du die XML Datei nach den Änderungen auch gespeichert? Wenn ja, und wenn dann trotzdem keine Änderung kommt, verhält sich die remove() Funktion aus dem Iterator ev. nicht so wie erwartet.
     
  7. Wambui
    Wambui Mitglied
    Nein, das habe ich tatsächlich komplett vergessen, bei dem gesamten gedanklichen Abstraktieren von XML nach Java. Vielen Dank für den Hinweis und die Erklärungen. Jetzt funktioniert Joose's Vorschlag.
     
  8. Hast du dir unsere Java-Grundlagen hier schon gesichert? *Klick*
Die Seite wird geladen...

XML-Element komplett löschen - Ähnliche Themen

JAXB: XML-Elemente einlesen und als XML-Attribute ausgeben
JAXB: XML-Elemente einlesen und als XML-Attribute ausgeben im Forum XML und Co.
XML-Element als String ausgeben
XML-Element als String ausgeben im Forum XML und Co.
Tabs/Einrückungen der XML-Elemente gehen beim Schreiben verloren
Tabs/Einrückungen der XML-Elemente gehen beim Schreiben verloren im Forum XML und Co.
XML-Elemente in Array speichern
XML-Elemente in Array speichern im Forum Java Basics - Anfänger-Themen
Kompletten String umwandeln in Integer
Kompletten String umwandeln in Integer im Forum Java Basics - Anfänger-Themen
Thema: XML-Element komplett löschen