XML-Element komplett löschen

Wambui

Aktives 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:
<?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:
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:

Harry Kane

Top Contributor
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.
 

Joose

Top Contributor
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.
 

Wambui

Aktives Mitglied
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.

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:
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:
                        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?
 

Harry Kane

Top Contributor
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.
 

Wambui

Aktives Mitglied
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.
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.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
8u3631984 jaxb XML Mapper - Root Element mit Attribut XML & JSON 20
B DOMParser - Element filtern XML & JSON 1
N jdom2 - Referenz auf Nested Element XML & JSON 2
H XML Element `Class` wird nicht gelesen XML & JSON 2
F xml Element ersetzen XML & JSON 5
M Text eines Elements in XML Datei mit JAVA bearbeiten und kompletten Element-Zweig hinzufügen XML & JSON 16
L XML nur ein Element einlesen XML & JSON 2
R XSD in einer choice mehrmals das selbe element möglich XML & JSON 5
S JDom XML ein Element hinzufügen. XML & JSON 1
ARadauer xsd ref auf element oder typen verwenden? XML & JSON 2
R cvc-complex-type.3.2.2: Attribute 'uuid' is not allowed to appear in element 'jasperReport'. XML & JSON 4
F EMF, XSD to ECore mapping, Attribute vs. Element XML & JSON 2
C xml validierung gegen xsd mit jdom: Fehlermeldung Cannot find the declaration of element ... XML & JSON 8
Landei JAXB: Wert von übergeordneten Element XML & JSON 4
N Alle namespaces ins Root Element hinauf ziehen XML & JSON 2
N Alle namespaces ins Root Element hinauf ziehen XML & JSON 2
S Validierung mit JAXB2 ohne root-element XML & JSON 10
E xml Element sortieren XML & JSON 2
T Xpath & JDOM Element Pfad ausgeben XML & JSON 2
Z XML parsen - Element mit Werten XML & JSON 2
enne87 Element-Werte werden falsch ausgelesen XML & JSON 2
M XSD - Child Element möglich, aber nicht zwingend erforderlich XML & JSON 6
N Individuelles Wrapper-Element um Collection mit JAXB XML & JSON 6
W Element mit XPath @id ermitteln wenn nur ein teil der id bekannt ist XML & JSON 2
R Element - Ausgeben von Kommentar XML & JSON 4
L Element manipulieren in einem DOMResult per XPath XML & JSON 10
G mit Transformer.transform ein Element überschreiben XML & JSON 2
G XSL: Element über eine Variable ermitteln XML & JSON 4
sparrow JDom Element.getChild("Name") liefert null obwohl vorhanden XML & JSON 4
B XML-Element als String ausgeben XML & JSON 5
L Element einlesen <Telefon name="Karl">134313 XML & JSON 2
S Cannot find the declaration of element XML & JSON 2
M Jaxb Annotationen, Wert als XML Element XML & JSON 2
O XML Element mit ":" im Namen XML & JSON 23
G Element mit Text und Unterelement XML & JSON 2
S Ampersand im Jdom-Element XML & JSON 2
C jdom.Element nicht vorhanden? XML & JSON 4
W JDOM element ändern funzt nich :( [problem gelöst] XML & JSON 3
M XML einlesen - prüfen ob Element vorhanden XML & JSON 2
F choice-Element mit minOccurs=0" XML & JSON 11
X Xpath, alle Element die mit "user" beginnen auswäh XML & JSON 2
C Mehrere Element_Nodes zusammenfassen zu einem Element XML & JSON 9
K Auf bestimmtes Element im XML zugreifen XML & JSON 3
M JDOM und XPath, zu Element zugehörigen XPath-Ausdruck XML & JSON 5
H Adapter: String->Element bzw. Element->String XML & JSON 6
M JDOM Element ohne Inhalt kopieren ? XML & JSON 3
S String in element casten XML & JSON 2
S Element hinzufügen XML & JSON 2
B Element an bestimmter Stelle einfügen (JDOM) XML & JSON 8
S zum element Attribut xmlns zufügen XML & JSON 6
N bestimmtes Element auslesen - ich verzweifel XML & JSON 3
J [Newbie] [JDOM] Element aus XML entfernen klappt nicht XML & JSON 4
P [Solved] XSL: Element-Variable auslesen XML & JSON 2
Noar XSLT - Element-Wrapping XML & JSON 2
R JDOM Root-Element entfernen aber Rest behalten XML & JSON 10
S Element addContent(Element) gibts nicht XML & JSON 5
R node.getNodeValue() bringt mir komplettes CDATA-Element XML & JSON 3
W Element Liste in Root XML & JSON 5
D Text, String vor einem Root Element einfügen XML & JSON 2
W root element parsen,Hilfe! XML & JSON 5
E Element.setTextContent(String); Ersatz fuer Version 1.4? XML & JSON 3
A NullPointerException bei leerem Element XML & JSON 4
D XML: Element section content does not follow the DTD XML & JSON 6
clemson element mit id in jdom löschen XML & JSON 2
A Element an einer bestimmten Stelle einfügen (nicht am Ende) XML & JSON 4
R JDom: XML Code von Element, und: ist Element ein standalone XML & JSON 2
N Probleme bei der Formatierung beim Einfügen und löschen über DOM XML & JSON 7
D XML Eintrag löschen XML & JSON 5
E Regex, erste ziffern löschen XML & JSON 4
B Problem beim löschen von ChildNodes aus einem XML-DOM XML & JSON 3
console xml knoten mit attribut löschen XML & JSON 3
D Kann man neue Knoten löschen? XML & JSON 4
H Nach einem Attribut suchen und dann löschen XML & JSON 3
T Elemente aus XML-File löschen (JDom) XML & JSON 9

Ähnliche Java Themen

Neue Themen


Oben