Java: Create a KML File and insert elements in existing file - java

I`m developing an app that reads the GPS-Exif Information of Photos and writes the Tags (Lat/Lon,...) in an KML or CSV File.
Creating the Files if they dont exist, especially the csv, is not the problem, but in this case i want to add a new KML- placemark to an existing KML-file.
so far i have created a method that checks if the file already exists - if not (if-statement) it creates a new one.
and if the file exists it should add the information (else).
public void createKMLFile(){
String kmlstart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n";
String kmlelement ="\t<Placemark>\n" +
"\t<name>Simple placemark</name>\n" +
"\t<description>"+name+"</description>\n" +
"\t<Point>\n" +
"\t\t<coordinates>"+latlon[1]+","+latlon[0]+","+z+ "</coordinates>\n" +
"\t</Point>\n" +
"\t</Placemark>\n";
String kmlend = "</kml>";
ArrayList<String> content = new ArrayList<String>();
//content.add(0,kmlstart);
//content.add(1,kmlelement);
//content.add(2,kmlend);
String kmltest;
//Zum Einsetzen eines Substrings (weitere Placemark)
//String test = "</kml>";
//int index = kml.lastIndexOf(test);
File test = new File(datapath+"/"+name+".kml");
Writer fwriter;
if(test.exists() == false){
try {
content.add(0,kmlstart);
content.add(1,kmlelement);
content.add(2,kmlend);
kmltest = content.get(0) + content.get(1) + content.get(2);
fwriter = new FileWriter(datapath+"/"+name+".kml");
fwriter.write(kmltest);
//fwriter.append("HalloHallo", index, kml.length());
fwriter.flush();
fwriter.close();
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
else{
kmltest = content.get(0) + content.get(1) + content.get(2);
StringTokenizer tokenize = new StringTokenizer(kmltest, ">");
ArrayList<String> append = new ArrayList<String>();
while(tokenize.hasMoreTokens()){
append.add(tokenize.nextToken());
append.add(1, kmlelement);
String rewrite = append.toString();
try {
fwriter = new FileWriter(datapath+"/"+name+".kml");
fwriter.write(rewrite);
fwriter.flush();
fwriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I dont get any Logs in the LogCat but the App stops working if i try to update the existing file... any suggestions?
thanks in advance
EDIT: Ok i see that content.add(0, kml...) has to be outside the try block... but thats not the main problem it seems

When modifying XML files it is best accomplished using a library of some sort. I maintain the XML-manipulation library called JDOM which is designed to make this sort of manipulation as easy as it can. Other options are using the DOM library (which is already built in to the Java runtime which makes it much easier to integrate in to your program), and SAX (which, in this case, I would not recommend, even though it may be faster). Other external libraries (like JDOM) exist which would also help, like XOM, dom4j, etc. This stackoverflow answer seems relevant: Best XML parser for Java
In JDOM, your code would look something like:
Document doc = null;
Namespace kmlns = new Namespace("http://www.opengis.net/kml/2.2");
Element position = new Element("Position", kmlns);
position.addContent(new Element("name", kmlns).setText(positionName));
position.addContent(new Element("desc", kmlns).setText(description));
position.addContent(..... all the XML content needed for the Position ....);
// create the XML Document in memory if the file does not exist
// otherwise read the file from the disk
if(!test.exists()){
doc = new Document();
Element root = new Element("kml", kmlns);
} else {
SAXBuilder sb = new SAXBuilder();
doc = sb.build(test);
}
Element root = doc.getRootElement();
// modify the XML as you need
// add Position Element
root.addContent(position);
try {
fwriter = new FileWriter(datapath+"/"+name+".kml");
XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat());
xout.output(doc, writer);
fwriter.flush();
fwriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
EDIT: you ask what's wrong with your actual code.... There are a few things that are contributing to your problems, but you don't show an actual error, or other indication of how the program 'stops working'.
there are bugs in your code which should throw serious exceptions: kmltest = content.get(0) + content.get(1) + content.get(2); should throw IndexOutOfBoundsException because the content ArrayList is empty (the lines adding values to the ArrayList are commented out....) - but let's assume that they are not....
You never read the file you are changing, so how can you be changing it?
The StringTokenizer delimeter is ">", which is never a good way to parse XML.
You loop through the String tokenizer on evert '>' delimeter, but you never add the token back in to the output (i.e. your output is milling a lot of '>' characters).
You add the kmlelement Position content in the place of every '>' caracter in the document, not just the one that is important.
The FileWriter logic should be ** outside** the loop.... you do not want to modify the file for every token you modify.

It´s working now, thanks for your input rolfl!
In my programm i have implemented the method with the JDOM library which is much more comfortable, anyhow here is the working code of my first try if someone is interested.
The output is not in a pretty format but the kml-file is working..
public void createKMLFile(){
String kmlstart = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n";
String kmlelement ="\t<Placemark>\n" +
"\t<name>Simple placemark</name>\n" +
"\t<description>"+name+"</description>\n" +
"\t<Point>\n" +
"\t\t<coordinates>"+latlon[1]+","+latlon[0]+","+z+ "</coordinates>\n" +
"\t</Point>\n" +
"\t</Placemark>\n";
String kmlend = "</kml>";
ArrayList<String> content = new ArrayList<String>();
content.add(0,kmlstart);
content.add(1,kmlelement);
content.add(2,kmlend);
String kmltest = content.get(0) + content.get(1) + content.get(2);
File testexists = new File(datapath+"/"+name+".kml");
Writer fwriter;
if(!testexists.exists()){
try {
fwriter = new FileWriter(datapath+"/"+name+".kml");
fwriter.write(kmltest);
fwriter.flush();
fwriter.close();
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
else{
//schleifenvariable
String filecontent ="";
ArrayList<String> newoutput = new ArrayList<String>();;
try {
BufferedReader in = new BufferedReader(new FileReader(testexists));
while((filecontent = in.readLine()) !=null)
newoutput.add(filecontent);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
newoutput.add(2,kmlelement);
String rewrite ="";
for(String s : newoutput){
rewrite += s;
}
try {
fwriter = new FileWriter(datapath+"/"+name+".kml");
fwriter.write(rewrite);
fwriter.flush();
fwriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Related

How do I print the next element in a linked list to a CSV file?

I'm making an address book and my program is supposed to save each element in a list to a CSV file. I've gotten everything to work asside from the fact that it will only save 1 line to the file.
public static void save(){
PrintWriter writer = null;
try {
writer = new PrintWriter("C:\\Users\\Remixt\\workspace\\2\\AddressBook.csv", "UTF-8");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(0);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(0);
}
{
writer.println(AddressBook.get(getListSize()-1)+"\n");
writer.close();//saves file
}
Edit: It will only save the last element to the file. It only shows 1 thing in the file no matter how many times i add something else to the list.
the problem is here
writer.println(AddressBook.get(getListSize()-1)+"\n");
you just write the last element of AddressBook to the csv file, use for loop
the following is a sample
for (int i = 0; i < AddressBook.size(); i++) {
writer.println(AddressBook.get(i)+"\n");
}
at last, you should write file by append mode
filename=new FileWriter("printWriter.txt",true);
writer=new java.io.PrintWriter(filename);

xml format in stanford pos tagger

i have tagged 20 sentences and this is my code:
public class myTag {
public static void main(String[] args) {
Properties props = new Properties();
try {
props.load(new FileReader("D:/tagger/english-bidirectional-distsim.tagger.props"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MaxentTagger tagger = new MaxentTagger("D:/tagger/english-bidirectional-distsim.tagger",props);
//==================================================================================================
try (BufferedReader br = new BufferedReader(new FileReader("C:/Users/chelsea/Desktop/EN/EN.txt")))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
String tagged = tagger.tagString(sCurrentLine);
System.out.println(tagged);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
this is the output:
as you can see in sentence node it has a Id attribute and here it's constantly=0 which it should not be.i expect the value=0,1,2,3,4,...
i don't understand what is wrong with my code.
Stanford POS tagger (strictly speaking, sentence splitter that is applied before POS annotator) generates ids for sentences per input text.
So, you ask tagger to tag sCurrentLine consisting of one sentence, this text is split into sentences - actually, just one, with id = 0; then you ask to tag another text - sCurrentLine from the next iteration - and it again is the only sentence and thereby it is the first sentence with id = 0; and so on.
Thus, if you want correct ids, firstly create the whole text, then pass it to tagger. However, if your input text is already split by sentences, it'll be better to leave things as they are (and generate ids by yourself in the loop, if you need them).

ReplaceAll not working on XML input

I am working on a java program that reads in XML and generates an output XML. I am having a problem replacing some of the characters in my read in file.
The following is my method:
public void readTemplateXML() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(
path), "UTF8"));
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String line;
StringBuilder sb = new StringBuilder();
try {
while ((line = br.readLine()) != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
xml = sb.toString();
xml = xml.replaceAll("<", "\\<"); //This is not working.
}
I am just outputting the "xml" string to an xml file and I am still getting "<":
<addressLine1>Main Street</addressLine1>
Is there anyway I can replace these characters with <, > ?
The encoding of the file is UTF-8.
EDIT:
the xml string is correct after the replace alls. I am using it as text content in another methods xml node:
// inner request element
Element request = doc.createElement("con:request");
request.appendChild(doc.createTextNode(xml));
rootElement.appendChild(request);
After this the content is incorrect.
Any help would be greatly appreaciated.
short answer :
Syntax:
Here is the syntax of this method:
public String replaceAll(String regex, String replacement)
Parameters:
Here is the detail of parameters:
regex -- the regular expression to which this string is to be matched.
replacement -- the string which would replace found expression.
code :
String xml="<addressLine1>Main Street</addressLine1>&#13";
xml = xml.replaceAll("<", "\\<");
xml = xml.replaceAll(">", "\\>");
xml = xml.replaceAll("&#13", "");
System.out.println( xml );
result :
<addressLine1>Main Street</addressLine1>

SetText String[] in a TextView

I am trying to use setText, and I want to use a String array. First, I create a String [], then I assign data to String[0], then I want to .setText(String[0]) on my TextView, is this the right way?
Note : I'm using a StringTokenizer to split Strings in the textfile
try {
filename = "myk.txt";
FileReader filereader = new FileReader(Environment.getExternalStorageDirectory() + "/Q/" + filename);
BufferedReader bufferedreader = new BufferedReader(filereader);
try {
while ((text = bufferedreader.readLine()) != null){
sb.append(text);
sb.toString().split(";");
tokens = new StringTokenizer(sb.toString(), ";");
///NULLPOINTER EXEPTION HERE//// if (tokens.countTokens() > 0){questionfromfile[0] = tokens.nextToken();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
////ETC ...//// and now textview.setText(question[0]);
Sure, you mean something like
String[] strings = new String [5];
strings[0] = "foobar";
component.setText(strings[0]);
why do you have this line:
sb.toString().split(";");
?
are you forgetting that a string is immutable ,meaning that using the standard API that you use , the string will never change itself , but create new objects instead?
about StringTokenizer, as javadocs say:
StringTokenizer is a legacy class that is retained for compatibility
reasons although its use is discouraged in new code. It is recommended
that anyone seeking this functionality use the split method of String
or the java.util.regex package instead.

Java File I/O - Text File - How to check for content?

I was wondering, If i had a java class, that wanted to consult a txt file with say a list of names like
tom
steve
jones
how could i open the text file in the java program and basically see if a string contained in the program matches one of these names?
so far i have come up with
try {
BufferedReader inputReader = new BufferedReader(new FileReader("users.txt"));
while (inputReader.readLine() != null){
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException ep) {
// TODO Auto-generated catch block
p.printStackTrace();
}
but do not no where to go from here..
You need to store the result of readLine(), like:
String nextLine;
while ((nextLine = inputReader.readLine()) != null){
if (nextLine.equals(stringToCheck)) {
//do something
}
}
(where stringToCheck is the target string, of course.)

Categories