我正在创建一个CRUD应用程序。就像在question here中一样,我能够在内存中修改XML文档,但是无法持久保存对XML文件的更改。
我已经使用了链接问题中提到的.transform()
方法。
Tiedosto.java包含用于打开XML文件并保存更改的方法:
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包含一种向文档添加新节点的方法:
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调用haeTuoterekisteri()
方法来打开文档,然后调用lisaaTuote()
方法来添加新节点。最后调用tallennaMuutokset()
方法,该方法应将更改保存到文件本身。这是问题所在:不会引发错误,更改也不会保存到XML文件。
<%@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>
原始的tuotteet.xml文件:
<?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