I'm creating a CRUD application. Just like in the question here, I am able to modify the XML document in memory, but I cannot persist changes to the XML file.
I'm already using the .transform()
method as mentioned in the linked question.
Tiedosto.java contains methods to open the XML file and save changes:
package tuoterekisteri;
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.net.*;
public class Tiedosto implements Serializable {
// luokan muuttujat
protected DocumentBuilderFactory tehdas = null;
protected DocumentBuilder rakentaja = null;
protected Document dokumentti = null;
protected URL polku = null;
protected File tiedosto = null;
protected DOMSource lahde = null;
protected TransformerFactory muuntajatehdas = null;
protected Transformer muuntaja = null;
protected StreamResult tulos = null;
protected StreamResult konsolitulos = null;
public Document getDokumentti() {
return this.dokumentti;
}
public boolean haeTuoterekisteri() {
boolean ok = true;
try {
polku = Tuoterekisteri.class.getResource("tuotteet.xml");
tiedosto = new File(polku.getFile());
tehdas = DocumentBuilderFactory.newInstance();
rakentaja = tehdas.newDocumentBuilder();
dokumentti = rakentaja.parse(this.tiedosto);
} catch (Exception e) {
e.printStackTrace();
ok = false;
}
return ok;
}
public boolean tallennaMuutokset() {
boolean ok = true;
try {
muuntajatehdas = TransformerFactory.newInstance();
muuntaja = muuntajatehdas.newTransformer();
lahde = new DOMSource(dokumentti);
tulos = new StreamResult(this.tiedosto);
muuntaja.transform(lahde, tulos);
// tulostus
konsolitulos = new StreamResult(System.out);
muuntaja.transform(lahde, konsolitulos);
} catch (Exception e) {
e.printStackTrace();
ok = false;
}
return ok;
}
}
Tuoterekisteri.java contains a method to add a new node to the document:
package tuoterekisteri;
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.net.*;
import java.util.*;
public class Tuoterekisteri extends Tiedosto {
// luokan muuttujat
int poistettavaid = 0;
int haettavaid = 0;
ArrayList<String> tiedot = new ArrayList<String>();
int poistettavaindeksi = 0;
public void lisaaTuote(String nimi, int hinta) {
try {
Element juuri = dokumentti.getDocumentElement();
Element uusituote = dokumentti.createElement("tuote");
Element eid = dokumentti.createElement("id");
eid.appendChild(dokumentti.createTextNode(String.valueOf(luoId())));
uusituote.appendChild(eid);
Element enimi = dokumentti.createElement("nimi");
enimi.appendChild(dokumentti.createTextNode(nimi));
uusituote.appendChild(enimi);
Element ehinta = dokumentti.createElement("hinta");
ehinta.appendChild(dokumentti.createTextNode(String.valueOf(hinta)));
uusituote.appendChild(ehinta);
juuri.appendChild(uusituote);
} catch (Exception e) {
e.printStackTrace();
}
}
public int luoId() {
String id = "0";
NodeList tuotteet = this.dokumentti.getElementsByTagName("tuote");
for (int i = 0; i < tuotteet.getLength(); i++) {
Element tuote = (Element) tuotteet.item(i);
NodeList idt = tuote.getElementsByTagName("id");
id = idt.item(0).getTextContent();
}
int id2 = Integer.parseInt(id);
int luku = (id2 >= 0) ? (id2 += 1) : (id2 = 1);
return id2;
}
}
lisaa.jsp calls the haeTuoterekisteri()
method which opens the document and then calls the lisaaTuote()
method which adds the new node. Finally tallennaMuutokset()
method is called which should save the changes to the file itself. Here is the problem: no error is thrown and neither are the changes saved to the XML file.
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<jsp:useBean class="tuoterekisteri.Tuoterekisteri" id="tuoterekisteri"/>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>XML-tuoterekisteri</title>
</head>
<body>
<h1>Lisää tuote</h1>
<form method="post">
Nimi: <input type="text" name="nimi"><br>
Hinta: <input type="number" name="hinta"><br>
<input type="submit" name="nappi">
<input type="submit" name="peruuta" value="Peruuta">
</form>
<%
if (tuoterekisteri.haeTuoterekisteri() && request.getParameter("nappi") != null) {
String nimi = request.getParameter("nimi");
int hinta = Integer.parseInt(request.getParameter("hinta"));
tuoterekisteri.lisaaTuote(nimi, hinta);
if (tuoterekisteri.tallennaMuutokset() == true) {
System.out.println("lisäys ok");
} else {
System.out.println("lisäys epäonnistui");
}
}
if (request.getParameter("peruuta") != null) {
response.sendRedirect("/tuoterekisteri");
}
%>
</body>
</html>
Original tuotteet.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<tuotteet>
<tuote xml:id="1">
<id>1</id>
<nimi>Lapio</nimi>
<hinta>5</hinta>
</tuote>
<tuote xml:id="2">
<id>2</id>
<nimi>Kirves</nimi>
<hinta>10</hinta>
</tuote>
<tuote xml:id="3">
<id>3</id>
<nimi>Vasara</nimi>
<hinta>15</hinta>
</tuote>
<tuote xml:id="5">
<id>5</id>
<nimi>Porakone</nimi>
<hinta>20</hinta>
</tuote>
</tuotteet>
StreamResult(System.out):
<?xml version="1.0" encoding="UTF-8" standalone="no"?><tuotteet>
<tuote xml:id="1">
<id>1</id>
<nimi>Lapio</nimi>
<hinta>5</hinta>
</tuote>
<tuote xml:id="2">
<id>2</id>
<nimi>Kirves</nimi>
<hinta>10</hinta>
</tuote>
<tuote xml:id="3">
<id>3</id>
<nimi>Vasara</nimi>
<hinta>15</hinta>
</tuote>
<tuote xml:id="5">
<id>5</id>
<nimi>Porakone</nimi>
<hinta>20</hinta>
</tuote>
<tuote><id>6</id><nimi>asd</nimi><hinta>123</hinta></tuote><tuote><id>7</id><nimi>asd</nimi><hinta>123</hinta></tuote></tuotteet>lisäys ok