# XML Eintrag löschen



## Dommschwenker (27. Mai 2017)

Hallo,
seit kurzem bin ich daran eine XML-Datei zu erstellen, welche einen Fuhrpark enthält.
Bisher sieht die XML-Datei so aus:

```
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<fuhrpark>
    <autos>
        <auto>
            <id>1</id>
            <hersteller>Audi</hersteller>
            <typ>A1</typ>
        </auto>
        <auto>
            <id>2</id>
            <hersteller>BMW</hersteller>
            <typ>1er</typ>
        </auto>
        <auto>
            <id>3</id>
            <hersteller>Mercedes</hersteller>
            <typ>A-Klasse</typ>
        </auto>
    </autos>
    <motorraeder>
        <motorrad>
            <id>1</id>
            <hersteller>BMW</hersteller>
            <typ>S 1000 RR</typ>
        </motorrad>
        <motorrad>
            <id>2</id>
            <hersteller>Harley</hersteller>
            <typ>Davidson</typ>
        </motorrad>
    </motorraeder>
</fuhrpark>
```


Jetzt würde ich gerne ein Auto über die ID löschen.
Hierzu habe ich den folgende Zeilen genutzt:

```
try {
    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
    Document doc = docBuilder.parse(new File("database.xml"));
   
    String objects = "auto";
    String id = "2";
   
    NodeList nList = doc.getElementsByTagName(objects);
    for (int index = 0; index < nList.getLength(); index++) {
        Node node = nList.item(index);
        Element ele = (Element) node;
        if (ele.getElementsByTagName("id").item(0).getTextContent().equalsIgnoreCase(id)) {
            node = ele.getParentNode();
            doc.getDocumentElement().removeChild(node);
        }
    }
   
    doc.normalize();
    TransformerFactory traFactory = TransformerFactory.newInstance();
    Transformer tra = traFactory.newTransformer();
    DOMSource dom = new DOMSource(doc);
    StreamResult res = new StreamResult(new File("database.xml"));
    tra.transform(dom, res);
} catch (ParserConfigurationException e) {
    JOptionPane.showMessageDialog(null, "Fehlermeldung:\n\n" + e, "Titel-Fehlermeldung", JOptionPane.ERROR_MESSAGE);
} catch (TransformerException e) {
    JOptionPane.showMessageDialog(null, "Fehlermeldung:\n\n" + e, "Titel-Fehlermeldung", JOptionPane.ERROR_MESSAGE);
} catch (Exception e) {
    JOptionPane.showMessageDialog(null, "Fehlermeldung:\n\n" + e, "Titel-Fehlermeldung", JOptionPane.ERROR_MESSAGE);
    return null;
}
```

Wenn ich das jedoch ausführe, löscht er mir alle Autos, was nicht Ziel der Übung war 
Ich gehe mal davon aus, dass es mit der "node = ele.getParentNode()" zusammenhängt, ich weiß aber leider auch nicht, was ich anders machen kann, damit es funktioniert.
Was ich natürlich nicht möchte, wäre es die XML-Datei in Auto und Motorräder zu splitten.

Hat jemand in der Community eine Idee, wie ich das umsetzen kann?

Gruß
Dommschwenker


----------



## mrBrown (27. Mai 2017)

Dommschwenker hat gesagt.:


> Ich gehe mal davon aus, dass es mit der "node = ele.getParentNode()" zusammenhängt, ich weiß aber leider auch nicht, was ich anders machen kann, damit es funktioniert.


Naja - "node = ele.getParentNode()" weglassen.
node ist dein gesuchtes <auto>, wenn du dir davon den Parent holst, landest du natürlich bei <autos>, was du ja nicht möchtest.
(Benenn doch deine Variablen sinnvoller, dann wäre dir das eher aufgefallen )


----------



## Dommschwenker (27. Mai 2017)

Guten Abend,

ich habe jetzt einfach die Zeile weggelassen.

Dann bringt er mir jedoch die Fehlermeldung
"NOT_FOUND_ERR: Es wurde versucht, einen Knoten in einem Kontext zu referenzieren, in dem er nicht vorhanden ist."

Irgendwie mag er nicht so wie ich will


----------



## mrBrown (28. Mai 2017)

Ich kenn die Lib nicht im Detail, aber Versuch mal nList.remove...


----------



## Dommschwenker (28. Mai 2017)

Hallo,

finde lediglich was unter nList.item(index).remove... dort dann aber auch nur removeChild, was zur selben Fehlermeldung führt wie oben.

Habe daher mal spaßeshalber die XML angepasst. Sieht dann so aus:

```
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<autos>
    <auto>
        <id>1</id>
        <hersteller>Audi</hersteller>
        <typ>A1</typ>
    </auto>
    <auto>
        <id>2</id>
        <hersteller>BMW</hersteller>
        <typ>1er</typ>
    </auto>
    <auto>
        <id>3</id>
        <hersteller>Mercedes</hersteller>
        <typ>A-Klasse</typ>
    </auto>
</autos>
```

Wenn ich dann mein Projekt ausführe, kommt am Schluss die Datei raus.

```
<?xml version="1.0" encoding="UTF-8" standalone="no"?><autos>
    <auto>
        <id>1</id>
        <hersteller>Audi</hersteller>
        <typ>A1</typ>
    </auto>
   
    <auto>
        <id>3</id>
        <hersteller>Mercedes</hersteller>
        <typ>A-Klasse</typ>
    </auto>
</autos>
```

Hängt also anscheinend nicht nur mit dem "node = ele.getParentNode()" sondern auch mit den "zwei Root-Einträgen" zusammen.
Sieht also wohl so aus, als müsste ich den Schritt gehen und die XML-Datei in zwei Dateien trennen. 
Schade 

Falls noch jemand eine Idee hat, immer her damit 

Schönen Sonntag


----------



## HarleyDavidson (30. Mai 2017)

Also ich habe mal dein Programm debuggt.
Innerhalb des if-Statements bei

```
if (ele.getElementsByTagName("id").item(0).getTextContent().equalsIgnoreCase(id)) {
   node = ele.getParentNode();
   doc.getDocumentElement().removeChild(node);
}
```
Belegst du "node" mit dem Element "autos". 
Direkt in der nächsten Zeile löschst du also "autos" aus dem kompletten XML.
Um nur das Element "auto" mit der id=2 zu entfernen, musst du das so ändern:

```
if (ele.getElementsByTagName("id").item(0).getTextContent().equalsIgnoreCase(id)) {
   node = ele.getParentNode();
   node.removeChild( ele );
   //Schleife verlassen, die id gibt es ja hoffentlich nur einmal ;)
   break;
}
```


----------

