Can string lines directly inserted into XML file [duplicate] - java

I'm trying to store an ArrayList into an XML file so that I can retrieve the information later on and then display it back into the console.
Can someone show me the most effective way to do this?
EDIT:
Heres what I am trying to write into an external file
// new user is created
Bank bank = new Bank();
System.out.println("Enter your full name below (e.g. John M. Smith): ");
String name = scanner.nextLine();
System.out.println("Create a username: ");
String userName = scanner.nextLine();
System.out.println("Enter your starting deposit amount: ");
int balance = scanner.nextInt();
System.out.print(dash);
System.out.print("Generating your information...\n");
System.out.print(dash);
int pin = bank.PIN();
String accountNum = bank.accountNum();
User user = new User(name, userName, pin, accountNum, balance);
//new user gets added to the array list
Bank.users.add(user);
System.out.println(user);
This all creates a Bank user, which gets thrown into an ArrayList, then I want to store their information so that I can come back later and redisplay it.

public static void main(String[] args) {
// TODO Auto-generated method stub
WriteFile ob = new WriteFile();
ArrayList list = new ArrayList();
list.add(new details("A", 20, 1));
list.add(new details("B", 30, 2));
ob.writeXmlFile(list);
}
// Modify this below class as per your need
class details {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
int age;
int id;
public details() {
}
public details(String name_, int age_, int id_) {
name = name_;
age = age_;
id = id_;
}
// below class actually writed
public void writeXmlFile(ArrayList<details> list) {
try {
DocumentBuilderFactory dFact = DocumentBuilderFactory.newInstance();
DocumentBuilder build = dFact.newDocumentBuilder();
Document doc = build.newDocument();
Element root = doc.createElement("Studentinfo");
doc.appendChild(root);
Element Details = doc.createElement("Details");
root.appendChild(Details);
for (details dtl : list) {
Element name = doc.createElement("Name");
name.appendChild(doc.createTextNode(String.valueOf(dtl
.getName())));
Details.appendChild(name);
Element id = doc.createElement("ID");
id.appendChild(doc.createTextNode(String.valueOf(dtl.getId())));
Details.appendChild(id);
Element mmi = doc.createElement("Age");
mmi.appendChild(doc.createTextNode(String.valueOf(dtl.getAge())));
Details.appendChild(mmi);
}
// Save the document to the disk file
TransformerFactory tranFactory = TransformerFactory.newInstance();
Transformer aTransformer = tranFactory.newTransformer();
// format the XML nicely
aTransformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
aTransformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "4");
aTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
try {
// location and name of XML file you can change as per need
FileWriter fos = new FileWriter("./ros.xml");
StreamResult result = new StreamResult(fos);
aTransformer.transform(source, result);
} catch (IOException e) {
e.printStackTrace();
}
} catch (TransformerException ex) {
System.out.println("Error outputting document");
} catch (ParserConfigurationException ex) {
System.out.println("Error building document");
}
}

The way I do it is either using XStream or Jackson API (preferred) to serialize the java object to either a XML or a JSON file.
For example, see my XStream data provider I wrote for use with TestNG or JUnit parameterized tests.

How about using XMLEncoder/XMLDecoder?
http://docs.oracle.com/javase/6/docs/api/java/beans/XMLEncoder.html
Copy and paraphrasing from the javadoc.
ArrayList arr = new ArrayList();
// populate your array
XMLEncoder e = new XMLEncoder(BufferedOutputStream(
new FileOutputStream("Test.xml")));
e.writeObject(arr);
e.close();
Similarly, the reverse to decode.

Related

Using 3 threads to read with 1 scanner the content of a file.csv and adding the content in an ArrayList

I'm training with Java and this is the first time that I'm using threads with it. An exercise asked me to read from a .cvs file and as a bonus it's asking me to use 3 threads to read this file and save the information in the same ArrayList<CustomClass>. I should have some kind of problem because every thread must read an unique line from the file.
This file contains this:
Clienti
nome,cognome,tipoMezzo,tipoParcheggio,dataOperazione,Operazione
Paolo,Rossi,cabrio,coperto,07/12/2022 09:00,0
Chiara,Bianchi,moto,aperto,07/12/2022 09:01,0
Abbondazio,Addolorata,4x4,aperto,07/12/2022 09:10,0
Agamennone,Agatangelo,moto,coperto,07/12/2022 09:11,0
Aldebrando,Barachisio,berlina,coperto,07/12/2022 09:12,0
Aldighiero,Barbaziano,moto,aperto,07/12/2022 10:01,0
Aldobrando,Bardomiano,moto,coperto,07/12/2022 10:05,0
Angilberto,Barsanufio,cabrio,aperto,07/12/2022 10:06,0
public class CarParkingImpl implements CarParking {
ArrayList<Cliente> lista;
byte coperto;
byte aperto;
public CarParkingImpl(){
coperto=30;
aperto =50;
lista = new ArrayList<Cliente>();
}
//This function must work with 3 operating Threads that read the same .cvs file and are syncronize to read each one a different line and put the information readed in the ArrayList 'lista'
#Override
public void carParkingFromCSV(String filePath) throws FileNotFoundException {
Scanner scan = new Scanner(new File(filePath));
scan.next();
scan.next();
while(scan.hasNext()){
String[] clientInfo1 = scan.next().split(",");
String[] clientInfo2 = scan.next().split(",");
String[] daySplit = clientInfo1[4].split("/");
String[] timeSplit = clientInfo2[0].split(":");
Calendar tempCalendar = Calendar.getInstance();
tempCalendar.set(Integer.parseInt(daySplit[2]),Integer.parseInt(daySplit[1])-1,Integer.parseInt(daySplit[0]),Integer.parseInt(timeSplit[0]),Integer.parseInt(timeSplit[1]));
Cliente tempClient = new Cliente(clientInfo1[0],clientInfo1[1],clientInfo1[2],clientInfo1[3],tempCalendar,Byte.parseByte(clientInfo2[1]));
try {
carParkingClient(tempClient);
}catch (CarParkingIsFullException e){
System.err.println(e.getMessage());
}
}
scan.close();
}
}
public class Cliente {
String name;
String surname;
String carType;
String parkReq;
Calendar dateOperation;
Byte parkOperation;
public Cliente(String name, String surname, String carType, String parkReq, Calendar dateOperation, Byte parkOperation) {
this.name = name;
this.surname = surname;
this.carType = carType;
this.parkReq = parkReq;
this.dateOperation = dateOperation;
this.parkOperation = parkOperation;
}
}
public class Main {
public static void main(String[] args) throws FileNotFoundException {
String path = "Clienti.csv";
String outPath = "Report.txt";
CarParkingImpl carParking = new CarParkingImpl();
try {
carParking.carParkingFromCSV(path);
carParking.printReport(outPath);
}catch (FileNotFoundException e){
System.err.println(e.getMessage());
}catch (IOException e){
System.err.println(e.getMessage());
}
}
}

Storing Objects of an array into CSV file and reading them with specific arguments for GUI

As a part of my assignment I had to store objects of an array in a flat-file and retrieve them when certain criteria was met. I can save the objects fine but when retrieving them I have an issue with getting more than one value, I understand what is going wrong but I am struggling to find a solution. Here is the concept of whats happening.
Button no 10,A (R1S10 in the code)is my testing button, When I click it it creates an event that I will show below.
Click event for button 10A -
private void R1S10ActionPerformed(java.awt.event.ActionEvent evt) {
seats.add(seat1);
if (R1S10.getBackground().equals(Color.red) &&(IsSeatBooked().equals("true"))){
Component frame = null;
JOptionPane.showMessageDialog(frame, "Seat UnBooked");
seat1.setBooked("false");
seat1.setName("");
R1S10.setBackground(Color.yellow);
try {
reader();
writer();
//String booked = "true";
//Pass String booked into csv file
} catch (IOException ex) {
Logger.getLogger(SeatingPlan.class.getName()).log(Level.SEVERE, null, ex);
}
}
else{
Component frame = null;
String name = JOptionPane.showInputDialog(frame, "Please enter name of Customer booking");
if (name.isEmpty()) {
JOptionPane.showMessageDialog(frame, "No value entered");
} else if (name != null) {
seat1.setName(name);
seat1.setBooked("true");
R1S10.setBackground(Color.red);
JOptionPane.showMessageDialog(frame, "Your Booking has been placed");
try {
writer();
reader();
//String booked = "true";
//Pass String booked into csv file
} catch (IOException ex) {
Logger.getLogger(SeatingPlan.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Followed by the screen below -
Outcome -
And when the button is pressed again -
I am using three methods in this SeatingPlan.java - writer(),reader() and IsSeatBooked().
SeatingPlan -
public class SeatingPlan extends javax.swing.JFrame {
/**
* Creates new form SeatingPlan
*/
String seatNo, name, bookedSeat;
FileWriter fileWriter = null;
List<Seat> seats = new ArrayList<Seat>();
//Seat Object Declaration
Seat seat1 = new Seat("R1S10","","false");
Seat seat2 = new Seat("R1S9", "", "false");
String fileName = "seat.csv";
writer -
public void writer() throws IOException {
//Delimiter used in CSV file
final String NEW_LINE_SEPARATOR = "\n", COMMA_DELIMITER = ",";
//CSV file header
final String FILE_HEADER = "seatID,name,booked";
//fileName = System.getProperty("user.home") + "/seat.csv";
try {
fileWriter = new FileWriter(fileName);
//Write the CSV file header
fileWriter.append(FILE_HEADER.toString());
//Add a new line separator after the header
fileWriter.append(NEW_LINE_SEPARATOR);
//Write a new student object list to the CSV file
for (Seat seat : seats) {
fileWriter.append(String.valueOf(seat.getSeatID()));
fileWriter.append(COMMA_DELIMITER);
fileWriter.append(seat.getName());
fileWriter.append(COMMA_DELIMITER);
fileWriter.append(seat.isBooked());
fileWriter.append(NEW_LINE_SEPARATOR);
}
System.out.println("CSV file was created successfully !!!");
} catch (Exception e) {
System.out.println("Error in CsvFileWriter !!!");
e.printStackTrace();
} finally {
fileWriter.flush();
fileWriter.close();
}
}
reader -
public void reader() {
//Delimiter used in CSV file
final String COMMA_DELIMITER = ",";
//Student attributes index
final int SEAT_ID_IDX = 0;
final int SEAT_NAME_IDX = 1;
final int SEAT_BOOKED = 2;
//private static final int STUDENT_LNAME_IDX = 2;
BufferedReader fileReader = null;
try {
//Create a new list of student to be filled by CSV file data
List<Seat> seats = new ArrayList<>();
String line = "";
//Create the file reader
fileReader = new BufferedReader(new FileReader(fileName));
//Read the CSV file header to skip it
fileReader.readLine();
//Read the file line by line starting from the second line
while ((line = fileReader.readLine()) != null) {
//Get all tokens available in line
String[] tokens = line.split(COMMA_DELIMITER);
if (tokens.length > 0) {
//Create a new seat object and fill his data
Seat seat = new Seat(tokens[SEAT_ID_IDX],
tokens[SEAT_NAME_IDX], tokens[SEAT_BOOKED]);
seats.add(seat);
seatNo = tokens[SEAT_ID_IDX];
//System.out.println("Seat Number: " + seatNo);
bookedSeat = tokens[SEAT_BOOKED];
}
}
//Print the new student list
for (Seat seat : seats) {
System.out.println(seat.toString());
}
} catch (Exception e) {
System.out.println("Error in CsvFileReader !!!");
e.printStackTrace();
} finally {
try {
fileReader.close();
} catch (IOException e) {
System.out.println("Error while closing fileReader !!!");
e.printStackTrace();
}
}
}//end reader
SeatingPlan - This if where I have tried to have the arguments controlling the outcome but IsBooked is colliding when multiple seats are selected.
public SeatingPlan() throws IOException {
setVisible(true);
initComponents();
//reader();
ColourSectionGold();
ColourSectionBronze();
reader();
if(R1S10.getBackground().equals(Color.yellow) && (IsSeatBooked().equals("true"))){ R1S10.setBackground(Color.red);}
//if(R1S9.getBackground().equals(Color.yellow) && (IsSeatBooked().equals("true2"))){ R1S9.setBackground(Color.red);}
}
IsSeatBooked -
public String IsSeatBooked(){
return bookedSeat;
}//end IsSeatBooked
Im using the method above as my argument to see whether a seat is booked or not, but when a new seat is click it sets the whole value of 'bookedSeat' - which leaves the system not working correctly. I understand the code is not very efficient but is there any temporary fix for this problem, if I have explained it correctly.
Also I will include my class for Seat -
public class Seat {
private String seatID;
private String booked;
private String name;
private int price;
public Seat(String seatID,String name,String booked){
this.seatID = seatID;
this.booked = "";
this.name = name;
this.price = price;
}
public String getSeatID() {
return seatID;
}
public void setSeatID(String seatID) {
this.seatID = seatID;
}
public String isBooked() {
return booked;
}
public void setBooked(String booked) {
this.booked = booked;
}
public String getStatus(){
return booked;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setPrice() {
this.price = price;
}}//end class Seat
And a look at the CSV file that is created -
I wish to be able to click more than one button and save its state, Button 10 works fine at the moment, but as IsBooked only has one value at a time it clashes.
If you took the time to check this out, I appreciate it. Any constructive criticism is helpful and any ideas would be great!
Thanks,
Paddy.
Too much code to look at to see exactly what you are doing.
Instead of using your csv file, you could create a Properties file. The Propertiesfile will store the data in the form of:
key:data
So in your case the key would be the id: A1, A2... and the data would be the name of the person who booked the seat.
So the file would start out as empty. When you create the GUI you would create a loop that checks each id to see if an entry is found in the Properties field. If it is found then you display the seat as taken, otherwise it is empty.
Then whenever you want to book a seat you just use the setProperty(...) method.
The Properties class has load(...) and store(...) methods.
So the Properties class allows you to easily manage a flat file database with minimal effort.
Note, you would never have variable names like R1S10. That would requirement 100 different variables with if/else statements. Instead you would extend JButton and pass in the row and seat as parameters the button. Then in the ActionListener for the button you can access the row/seat information to built the ID used as the key for the properties file.
Edit:
Couldn't quite make the loop that checks if the ID is in the properties file.
If the property is null, the seath is empty.
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Properties properties = new Properties();
properties.setProperty("A2", "Smith");
properties.setProperty("C3", "Jones");
String[] rows = { "A", "B", "C", "D" };
int seats = 4;
for (int row = 0; row < rows.length; row++)
{
for (int seat = 1; seat <= seats; seat++)
{
String key = rows[row] + seat;
String property = properties.getProperty( key );
System.out.println(key + " : " + property);
}
}
}
}

How to write a unit test for an XML parser I wrote in Java

The context is as follows:
I've got objects that represent Tweets (from Twitter). Each object has an id, a date and the id of the original tweet (if there was one).
I receive a file of tweets (where each tweet is in the format of 05/04/2014 12:00:00, tweetID, originalID and is in its' own line) and I want to save them as an XML file where each field has its' own tag.
I want to then be able to read the file and return a list of Tweet objects corresponding to the Tweets from the XML file.
After writing the XML parser that does this I want to test that it works correctly. I've got no idea how to test this.
The XML Parser:
public class TweetToXMLConverter implements TweetImporterExporter {
//there is a single file used for the tweets database
static final String xmlPath = "src/main/resources/tweetsDataBase.xml";
//some "defines", as we like to call them ;)
static final String DB_HEADER = "tweetDataBase";
static final String TWEET_HEADER = "tweet";
static final String TWEET_ID_FIELD = "id";
static final String TWEET_ORIGIN_ID_FIELD = "original tweet";
static final String TWEET_DATE_FIELD = "tweet date";
static File xmlFile;
static boolean initialized = false;
#Override
public void createDB() {
try {
Element tweetDB = new Element(DB_HEADER);
Document doc = new Document(tweetDB);
doc.setRootElement(tweetDB);
XMLOutputter xmlOutput = new XMLOutputter();
// display nice nice? WTF does that chinese whacko want?
xmlOutput.setFormat(Format.getPrettyFormat());
xmlOutput.output(doc, new FileWriter(xmlPath));
xmlFile = new File(xmlPath);
initialized = true;
} catch (IOException io) {
System.out.println(io.getMessage());
}
}
#Override
public void addTweet(Tweet tweet) {
if (!initialized) {
//TODO throw an exception? should not come to pass!
return;
}
SAXBuilder builder = new SAXBuilder();
try {
Document document = (Document) builder.build(xmlFile);
Element newTweet = new Element(TWEET_HEADER);
newTweet.setAttribute(new Attribute(TWEET_ID_FIELD, tweet.getTweetID()));
newTweet.setAttribute(new Attribute(TWEET_DATE_FIELD, tweet.getDate().toString()));
if (tweet.isRetweet())
newTweet.addContent(new Element(TWEET_ORIGIN_ID_FIELD).setText(tweet.getOriginalTweet()));
document.getRootElement().addContent(newTweet);
} catch (IOException io) {
System.out.println(io.getMessage());
} catch (JDOMException jdomex) {
System.out.println(jdomex.getMessage());
}
}
//break glass in case of emergency
#Override
public void addListOfTweets(List<Tweet> list) {
for (Tweet t : list) {
addTweet(t);
}
}
#Override
public List<Tweet> getListOfTweets() {
if (!initialized) {
//TODO throw an exception? should not come to pass!
return null;
}
try {
SAXBuilder builder = new SAXBuilder();
Document document;
document = (Document) builder.build(xmlFile);
List<Tweet> $ = new ArrayList<Tweet>();
for (Object o : document.getRootElement().getChildren(TWEET_HEADER)) {
Element rawTweet = (Element) o;
String id = rawTweet.getAttributeValue(TWEET_ID_FIELD);
String original = rawTweet.getChildText(TWEET_ORIGIN_ID_FIELD);
Date date = new Date(rawTweet.getAttributeValue(TWEET_DATE_FIELD));
$.add(new Tweet(id, original, date));
}
return $;
} catch (JDOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Some usage:
private TweetImporterExporter converter;
List<Tweet> tweetList = converter.getListOfTweets();
for (String tweetString : lines)
converter.addTweet(new Tweet(tweetString));
How can I make sure the the XML file I read (that contains tweets) corresponds to the file I receive (in the form stated above)?
How can I make sure the tweets I add to the file correspond to the ones I tried to add?
Assuming that you have the following model:
public class Tweet {
private Long id;
private Date date;
private Long originalTweetid;
//getters and seters
}
The process would be the following:
create an isntance of TweetToXMLConverter
create a list of Tweet instances that you expect to receive after parsing the file
feed the converter the list you generated
compare the list received by parsing the list and the list you initiated at the start of the test
public class MainTest {
private TweetToXMLConverter converter;
private List<Tweet> tweets;
#Before
public void setup() {
Tweet tweet = new Tweet(1, "05/04/2014 12:00:00", 2);
Tweet tweet2 = new Tweet(2, "06/04/2014 12:00:00", 1);
Tweet tweet3 = new Tweet(3, "07/04/2014 12:00:00", 2);
tweets.add(tweet);
tweets.add(tweet2);
tweets.add(tweet3);
converter = new TweetToXMLConverter();
converter.addListOfTweets(tweets);
}
#Test
public void testParse() {
List<Tweet> parsedTweets = converter.getListOfTweets();
Assert.assertEquals(parsedTweets.size(), tweets.size());
for (int i=0; i<parsedTweets.size(); i++) {
//assuming that both lists are sorted
Assert.assertEquals(parsedTweets.get(i), tweets.get(i));
};
}
}
I am using JUnit for the actual testing.

How to write an ArrayList to an XML file?

I'm trying to store an ArrayList into an XML file so that I can retrieve the information later on and then display it back into the console.
Can someone show me the most effective way to do this?
EDIT:
Heres what I am trying to write into an external file
// new user is created
Bank bank = new Bank();
System.out.println("Enter your full name below (e.g. John M. Smith): ");
String name = scanner.nextLine();
System.out.println("Create a username: ");
String userName = scanner.nextLine();
System.out.println("Enter your starting deposit amount: ");
int balance = scanner.nextInt();
System.out.print(dash);
System.out.print("Generating your information...\n");
System.out.print(dash);
int pin = bank.PIN();
String accountNum = bank.accountNum();
User user = new User(name, userName, pin, accountNum, balance);
//new user gets added to the array list
Bank.users.add(user);
System.out.println(user);
This all creates a Bank user, which gets thrown into an ArrayList, then I want to store their information so that I can come back later and redisplay it.
public static void main(String[] args) {
// TODO Auto-generated method stub
WriteFile ob = new WriteFile();
ArrayList list = new ArrayList();
list.add(new details("A", 20, 1));
list.add(new details("B", 30, 2));
ob.writeXmlFile(list);
}
// Modify this below class as per your need
class details {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
int age;
int id;
public details() {
}
public details(String name_, int age_, int id_) {
name = name_;
age = age_;
id = id_;
}
// below class actually writed
public void writeXmlFile(ArrayList<details> list) {
try {
DocumentBuilderFactory dFact = DocumentBuilderFactory.newInstance();
DocumentBuilder build = dFact.newDocumentBuilder();
Document doc = build.newDocument();
Element root = doc.createElement("Studentinfo");
doc.appendChild(root);
Element Details = doc.createElement("Details");
root.appendChild(Details);
for (details dtl : list) {
Element name = doc.createElement("Name");
name.appendChild(doc.createTextNode(String.valueOf(dtl
.getName())));
Details.appendChild(name);
Element id = doc.createElement("ID");
id.appendChild(doc.createTextNode(String.valueOf(dtl.getId())));
Details.appendChild(id);
Element mmi = doc.createElement("Age");
mmi.appendChild(doc.createTextNode(String.valueOf(dtl.getAge())));
Details.appendChild(mmi);
}
// Save the document to the disk file
TransformerFactory tranFactory = TransformerFactory.newInstance();
Transformer aTransformer = tranFactory.newTransformer();
// format the XML nicely
aTransformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
aTransformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "4");
aTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
try {
// location and name of XML file you can change as per need
FileWriter fos = new FileWriter("./ros.xml");
StreamResult result = new StreamResult(fos);
aTransformer.transform(source, result);
} catch (IOException e) {
e.printStackTrace();
}
} catch (TransformerException ex) {
System.out.println("Error outputting document");
} catch (ParserConfigurationException ex) {
System.out.println("Error building document");
}
}
The way I do it is either using XStream or Jackson API (preferred) to serialize the java object to either a XML or a JSON file.
For example, see my XStream data provider I wrote for use with TestNG or JUnit parameterized tests.
How about using XMLEncoder/XMLDecoder?
http://docs.oracle.com/javase/6/docs/api/java/beans/XMLEncoder.html
Copy and paraphrasing from the javadoc.
ArrayList arr = new ArrayList();
// populate your array
XMLEncoder e = new XMLEncoder(BufferedOutputStream(
new FileOutputStream("Test.xml")));
e.writeObject(arr);
e.close();
Similarly, the reverse to decode.

How to append to xml table with java?

Okay so I'm creating a users class which asks for input then stores it in an XML file using java. I figured out to create the original XML file I think but I'm have trouble figuring out how to add a new user with the attribute "id" of one more then the previous User entry.
Here is the code I have so far:
/*imports */
public class CreateUser {
static Scanner input = new Scanner(System.in);
/* object names*/
String name;
String age;
String bday;
String gender;
String location;
String orientation;
String relationship;
String hobbies;
String choice;
String username;
String password;
public void makeUser(){
/*left out code to get user entries here
seemed irrelevant/*
/*checks for file if it doesn't exist then it creates it else it should append
the user to the xml document with a id increase of one.
The appending part I'm not sure how to do.*/
File f = new File("C:\\Users\\Steven\\Workspace\\twitter\\src\\users.xml");
if(f.exists()) {
try {
/* need help here*/
}
}
else{
try{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document users = docBuilder.newDocument();
Element user = users.createElement("user");
users.appendChild(user);
Attr attr = users.createAttribute("id");
attr.setValue("0");
user.setAttributeNode(attr);
Element dname = users.createElement("name");
dname.appendChild(users.createTextNode(name));
user.appendChild(dname);
Element dgender = users.createElement("gender");
dgender.appendChild(users.createTextNode(gender));
user.appendChild(dgender);
Element dlocation = users.createElement("location");
dlocation.appendChild(users.createTextNode(location);
user.appendChild(dlocation);
Element dorientation = users.createElement("orientation");
dorientation.appendChild(users.createTextNode(orientation));
user.appendChild(dorientation);
Element drelationship = users.createElement("relationship");
drelationship.appendChild(users.createTextNode(relationship));
drelationship.appendChild(drelationship);
Element dhobbies = users.createElement("hobbies");
dhobbies.appendChild(users.createTextNode(hobbies));
dhobbies.appendChild(dhobbies);
Element dchoice = users.createElement("choice");
dchoice.appendChild(users.createTextNode(choice));
dchoice.appendChild(dchoice);
Element dusername = users.createElement("username");
dusername.appendChild(users.createTextNode(username));
dusername.appendChild(dusername);
Element dpassword = users.createElement("password");
dpassword.appendChild(users.createTextNode(password));
dpassword.appendChild(dpassword);
Element dbday = users.createElement("birthday");
dbday.appendChild(users.createTextNode(bday));
dbday.appendChild(dbday);
Element dage = users.createElement("age");
dage.appendChild(users.createTextNode(age));
dage.appendChild(dage);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(users);
StreamResult result = new StreamResult(new File("C:\\Users\\Steven\\Workspace\\twitter\\src\\users.xml"));
StreamResult test = new StreamResult(System.out);
transformer.transform(source, result);
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
}
I know its a lot of code to look through and I don't want an exact coded answer but maybe just how to append the user with the attribute value one more then the previous entry. Or a point in a the direction of a helpful website. Anything really I've been perplexed for a little and I feel like I should get something this simple. Thanks in advance for any help
In your first section(if block), I think you can open your file in append mode as below to add an user, assuming user node is not wrapped in another node.
StreamResult result = new StreamResult(
new FileWriter("C:\\Users\\Steven\\Workspace\\twitter\\src\\users.xml", true));
There are two changes in above statement:
Using FileWriter in place of File
Using a second parameter true, which open the file in append mode.
EDIT: To get the max existing ID, you need to read file and look for ID tag as below:
File xmlFile = new File("C:\\Users\\Steven\\Workspace\\twitter\\src\\users.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("userId");//use the id tag name
int maxId = 0;
for(Node node: nList){
if(Integer.parseInt(node.getTextContent()) > maxId ){
maxId = Integer.parseInt(node.getTextContent());
}
}
int newId = maxId +1; //use this ID
xmlFile.close();//close the file
Consider JAXB, here is a working example to start with:
static class Users {
private List<User> user = new ArrayList<>();
public List<User> getUsers() {
return user;
}
public void setUsers(List<User> users) {
this.user = users;
}
}
static class User {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public static void main(String[] args) throws Exception {
User user = new User();
user.setName("user1");
Users users = new Users();
users.setUsers(Arrays.asList(user));
JAXB.marshal(users, new File("users.xml"));
users = JAXB.unmarshal(new File("users.xml"), Users.class);
User user2 = new User();
user2.setName("user2");
users.getUsers().add(user2);
JAXB.marshal(users, System.out);
}
Consider SAX, unlike DOM it's fast and has no size limit. Here's a basic example:
public static void main(String[] args) throws Exception {
String xml = "<users><user><name>user1</name></user></users>";
XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("users")) {
addUser();
}
super.endElement(uri, localName, qName);
}
private void addUser() throws SAXException {
super.startElement("", "", "user", null);
addFileld("name", "user2");
super.endElement("", "", "user");
}
private void addFileld(String name, String value) throws SAXException {
super.startElement("", "", name, null);
super.characters(value.toCharArray(), 0, value.length());
super.endElement("", "", name);
}
};
Source src = new SAXSource(xr, new InputSource(new StringReader(xml)));
Result res = new StreamResult(System.out);
TransformerFactory.newInstance().newTransformer().transform(src, res);
}
output:
<users><user><name>user1</name></user><user><name>user2</name></user></users>

Categories

Resources