I am new to KML I have to make a KML file that contains some information about a place and that data should be displayed in Google map. I have written a code in java which will generate a KML as an output but I have some problem, the KML is not generating.
java.io.FileNotFoundException: c:\PlaceMarkers.kml (Access is denied) this is my error..
This is what I have done so far..
import java.io.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class GenKMLPlaceMarker {
public int id;
public String name;
public String address;
public float lat;
public float lng;
public String type;
public static void main(String[] args) {
Statement stmt;
ResultSet rs;
GenKMLPlaceMarker KML = new GenKMLPlaceMarker();
try {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/homeland";
Connection con = DriverManager.getConnection(url, "root", "root");
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
TransformerFactory tranFactory = TransformerFactory.newInstance();
Transformer aTransformer = tranFactory.newTransformer();
Document doc = builder.newDocument();
Element root = doc.createElement("kml");
root.setAttribute("xmlns", "http://earth.google.com/kml/2.1");
doc.appendChild(root);
Element dnode = doc.createElement("Document");
root.appendChild(dnode);
Element rstyle = doc.createElement("Style");
rstyle.setAttribute("id", "restaurantStyle");
Element ristyle = doc.createElement("IconStyle");
ristyle.setAttribute("id", "restaurantIcon");
Element ricon = doc.createElement("Icon");
Element riconhref = doc.createElement("href");
riconhref
.appendChild(doc
.createTextNode("http://maps.google.com/mapfiles/kml/pal2/icon63.png"));
rstyle.appendChild(ristyle);
ricon.appendChild(riconhref);
ristyle.appendChild(ricon);
dnode.appendChild(rstyle);
Element bstyle = doc.createElement("Style");
bstyle.setAttribute("id", "barStyle");
Element bistyle = doc.createElement("IconStyle");
bistyle.setAttribute("id", "barIcon");
Element bicon = doc.createElement("Icon");
Element biconhref = doc.createElement("href");
biconhref
.appendChild(doc
.createTextNode("http://maps.google.com/mapfiles/kml/pal2/icon27.png"));
bstyle.appendChild(bistyle);
bicon.appendChild(biconhref);
bistyle.appendChild(bicon);
dnode.appendChild(bstyle);
stmt = con.createStatement();
rs = stmt.executeQuery("SELECT * FROM markers");
while (rs.next()) {
KML.id = rs.getInt("id");
KML.name = rs.getString("name");
KML.address = rs.getString("address");
KML.lat = rs.getFloat("lat");
KML.lng = rs.getFloat("lng");
KML.type = rs.getString("type");
Element placemark = doc.createElement("Placemark");
dnode.appendChild(placemark);
Element name = doc.createElement("name");
name.appendChild(doc.createTextNode(KML.name));
placemark.appendChild(name);
Element descrip = doc.createElement("description");
descrip.appendChild(doc.createTextNode(KML.address));
placemark.appendChild(descrip);
Element styleUrl = doc.createElement("styleUrl");
styleUrl.appendChild(doc.createTextNode("#" + KML.type
+ "Style"));
placemark.appendChild(styleUrl);
Element point = doc.createElement("Point");
Element coordinates = doc.createElement("coordinates");
coordinates.appendChild(doc.createTextNode(KML.lng + ","
+ KML.lat));
point.appendChild(coordinates);
placemark.appendChild(point);
}
Source src = new DOMSource(doc);
Result dest = new StreamResult(new File("c:/PlaceMarkers.kml"));
aTransformer.transform(src, dest);
System.out.println("Completed.....");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
You can use Java API for KML
The objective of the Java API for KML is to provide Java interfaces for easy access to KML (Keyhole Markup Language) data.
The main goal of the Java API for KML (JAK) is to provide automatically generated full reference implementation of the KML object model defined by OGC’s KML standard and Google’s GX extensions. It is an object orientated API that enables the convenient and easy use of KML in existing Java environments.
Related
i am connecting to database of many servers to retrieve data from them all, i am using xml file contains the information of each database server [ip,port,user,passwd] followed by the query to be executed on that server. i read the queries in my code as arrayList and get them one by one to be processed. what i need is a clear simple code to also read the database server info to connect to it and execute the relative query , i.e. for each a query i need to get the database IP,port,user,passwd in my code. here is my xml file structure. thanks in adavnce.
<?xml version="1.0"?>
<Database>
<DB>
<ip></ip>
<port></port>
<user></user>
<pass></pass>
</DB>
<Query>
select date from myTable
</Query>
<DB>
<ip></ip>
<port></port>
<user></user>
<pass></pass>
</DB>
<Query>
select time from myTable
</Query>
<DB>
<ip></ip>
<port></port>
<user></user>
<pass><></pass>
</DB>
<Query>
select name from myTable
</Query>
</Database>
You can use Java's DOM api for xml processing and xpath.
DOM: https://docs.oracle.com/javase/tutorial/jaxp/dom/index.html
Xpath: http://www.w3schools.com/xsl/xpath_syntax.asp
Below is some sample code that does part of what you want (extracts the ip and port). You will need to modify it to do the rest:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DomTester {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
InputStream inStr = null;
try {
String xml = "<?xml version=\"1.0\"?>"
+ "<Database>"
+ "<DB>"
+ "<ip>666</ip>"
+ "<port>7</port>"
+ "</DB>"
+ "<DB>"
+ " <ip>13</ip>"
+ "<port>1</port>"
+ "</DB>"
+ "</Database>";
inStr = new ByteArrayInputStream(xml.getBytes());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(inStr);
XPathFactory xFactory = XPathFactory.newInstance();
XPath xpath = xFactory.newXPath();
XPathExpression expr = xpath.compile("/Database");
Element databaseEl = (Element)expr.evaluate(doc, XPathConstants.NODE);
NodeList databaseNodeList = databaseEl.getChildNodes();
for (int ii=0; ii<databaseNodeList.getLength(); ++ii) {
Node dbNode = databaseNodeList.item(ii);
XPathExpression ipExpr = xpath.compile("ip");
Element ipElement = (Element)ipExpr.evaluate(dbNode, XPathConstants.NODE);
String ip = ipElement.getTextContent();
XPathExpression portExpr = xpath.compile("port");
Element portEl = (Element)portExpr.evaluate(dbNode, XPathConstants.NODE);
String port = portEl.getTextContent();
System.out.println("DB node[" + ii + "] = ip: " + ip + " port: " + port);
}
} finally {
if (null != inStr) {
inStr.close();
}
}
}
}
Since you are reading from a file instead of using a string, instead of doing this:
inStr = new ByteArrayInputStream(xml.getBytes());
do this:
File f = new File("your/file/path.xml");
inStr = new FileInputStream(f);
I am trying to create a new file using java.io.File(String). If the filepath string contains '#' symbol means, created file's name gets truncated. Please anyone explain me why it's happening and how to create the filename with '#' from java.
My code.
new File("d:\\file#test.xml");
Expected output:
file#test.xml
Real output:
file
Note: I need to create the file in both windows and Unix file system.
Normally both windows and Unix systems are allowed to create a filename with #.
Edited:
Thanks to all your reply. yes, problem is not in java.io.File(String). Actually i am getting this problem when i am trying to create the xml file using xml transformer.
please find the full code below.
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class XMLWriterDOM {
public static void main(String[] args) {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
try {
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.newDocument();
//add elements to Document
Element rootElement =
doc.createElementNS("http://www.journaldev.com/employee", "Employees");
//append root element to document
doc.appendChild(rootElement);
//append first child element to root element
rootElement.appendChild(getEmployee(doc, "1", "Pankaj", "29", "Java Developer", "Male"));
//for output to file,
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
//for pretty print
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult file = new StreamResult(new File("d:\\\\emps#1.xml"));
//write data
transformer.transform(source, file);
System.out.println("DONE");
} catch (Exception e) {
e.printStackTrace();
}
}
private static Node getEmployee(Document doc, String id, String name, String age, String role,
String gender) {
Element employee = doc.createElement("Employee");
//set id attribute
employee.setAttribute("id", id);
//create name element
employee.appendChild(getEmployeeElements(doc, employee, "name", name));
//create age element
employee.appendChild(getEmployeeElements(doc, employee, "age", age));
//create role element
employee.appendChild(getEmployeeElements(doc, employee, "role", role));
//create gender element
employee.appendChild(getEmployeeElements(doc, employee, "gender", gender));
return employee;
}
//utility method to create text node
private static Node getEmployeeElements(Document doc, Element element, String name, String value) {
Element node = doc.createElement(name);
node.appendChild(doc.createTextNode(value));
return node;
}
}
Please suggest me to solve this issue.
I can't reproduce your problem under Mac OS X.
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main {
public static void main(String[] args) {
String temp = System.getProperty("java.io.tmpdir");
Path path = Paths.get(temp, "foo#bar.txt");
System.out.println(path.toAbsolutePath());
}
}
Output:
/var/folders/qm/0t0z2hfx6lb53gf7d8h2srzm0000gp/T/foo#bar.txt
What is the code that makes the output?
I would need to build a simple program for my homework purposes that will retrieve data from an XML attribute based on the user input in a web service. To that end, I assumed I would start building a class that could parse my XML string and also I built a simple java service that does nothing but responds with a simple message. The problem is how do I put these together in order to get my program to work? Is this a good way to begin with? Please advise.
Also, to make thing a little more easier, the data in the string representation of XML has key words in both English and Serbian that would enable this web service to retrieve from one another:
import java.io.IOException;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class Recnik {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE language [<!ATTLIST phrase id ID #IMPLIED>]><language id=\"sr\"><phrase key=\"house\" value=\"kuca\"/><phrase key=\"dog\" value=\"pas\"/><phrase key=\"cat\" value=\"macka\"/></language>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
//FileInputStream fis = new FileInputStream("myBooks.xml");
InputSource is = new InputSource(new StringReader(xmlString));
Document doc = db.parse(is);
Element r = doc.getDocumentElement();
NodeList language = r.getElementsByTagName("phrase");
System.out.println(language.item(1).getAttributes().item(0).getTextContent());
}
}
package Prevodilac;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
#WebService(serviceName = "Prevodilac")
public class Prevodilac {
#WebMethod(operationName = "pretraga")
public String pretraga(int a, int b) {
Integer res = a+b;
return res.toString();
}
}
#WebService(serviceName = "Prevodilac")
public class Prevodilac {
Document doc;
public Prevodilac() throws ParserConfigurationException, SAXException, IOException{
// Fill the document just once, not for each method call
String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE language [<!ATTLIST phrase id ID #IMPLIED>]><language id=\"sr\"><phrase key=\"house\" value=\"kuca\"/><phrase key=\"dog\" value=\"pas\"/><phrase key=\"cat\" value=\"macka\"/></language>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xmlString));
doc = db.parse(is);
}
#WebMethod(operationName = "pretraga")
public String pretraga(String key) {
Element r = doc.getDocumentElement();
NodeList language = r.getElementsByTagName("phrase");
String result = "Not found";
for( int index = 0; index < language.getLength(); index++ ) {
Node attribute = language.item(index).getAttributes().getNamedItem("key");
// TODO (It's homework after all):
// check if the attribute corresponds to key parameter
if( attribute..... ){
// fill result with attribute value
result = ...;
}
}
return result;
}
}
I have some classes that already use DOM4J to read XML files and provide
getter methods to the data. Now, I need to add the possibility of checking XML digital
signatures.
Using org.w3c.dom and following http://java.sun.com/developer/technicalArticles/xml/dig_signature_api/
everything works correctly.
So, I try to use DOMWriter to convert from org.dom4j.Document to
org.w3c.dom.Document, but after this the signature validation doesn't work. I think it
happens because DOMWiter is changing the XML tree (as doc4.asXML() seems to show).
I try to find something to set in order to mantain the integrity of the document, but
DOMWriter don't have such methods.
Below is the code demonstrating the asymmetric conversion.
The file used for tests is http://www.robertodiasduarte.com.br/files/nfe/131090007910044_v1.10-procNFe.xml
Does someone know reasons/workarounds to this?
Thanks (and sorry my poor english).
package testevalidanfe;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import javax.swing.JOptionPane;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.dom4j.io.XMLWriter;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public class Testevalidanfe {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document d = db.parse("exemplo-nfe.xml");
Node no = d.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature").item(0);
DOMValidateContext valContext = new DOMValidateContext(new X509KeySelector(), no);
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
XMLSignature signature = fac.unmarshalXMLSignature(valContext);
JOptionPane.showMessageDialog(null, "Validation using org.w3c.dom: " + signature.validate(valContext));
org.dom4j.io.DOMReader domreader = new org.dom4j.io.DOMReader();
org.dom4j.Document doc4 = domreader.read(d);
org.dom4j.io.DOMWriter domwriter = new org.dom4j.io.DOMWriter();
d = domwriter.write(doc4);
String after = doc4.asXML();
PrintWriter writer = new PrintWriter(new File("after-convertion.xml"));
writer.print(after);
writer.close();
no = d.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature").item(0);
valContext = new DOMValidateContext(new X509KeySelector(), no);
fac = XMLSignatureFactory.getInstance("DOM");
signature = fac.unmarshalXMLSignature(valContext);
JOptionPane.showMessageDialog(null, "Validation after convert: " + signature.validate(valContext));
}
}
package testevalidanfe;
import java.security.Key;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import javax.xml.crypto.AlgorithmMethod;
import javax.xml.crypto.KeySelector;
import javax.xml.crypto.KeySelectorException;
import javax.xml.crypto.KeySelectorResult;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.X509Data;
public class X509KeySelector extends KeySelector {
public KeySelectorResult select(KeyInfo keyInfo,
KeySelector.Purpose purpose,
AlgorithmMethod method,
XMLCryptoContext context)
throws KeySelectorException {
Iterator ki = keyInfo.getContent().iterator();
while (ki.hasNext()) {
XMLStructure info = (XMLStructure) ki.next();
if (!(info instanceof X509Data))
continue;
X509Data x509Data = (X509Data) info;
Iterator xi = x509Data.getContent().iterator();
while (xi.hasNext()) {
Object o = xi.next();
if (!(o instanceof X509Certificate))
continue;
final PublicKey key = ((X509Certificate)o).getPublicKey();
if (algEquals(method.getAlgorithm(), key.getAlgorithm())) {
return new KeySelectorResult() {
public Key getKey() { return key; }
};
}
}
}
throw new KeySelectorException("No key found!");
}
static boolean algEquals(String algURI, String algName) {
if ((algName.equalsIgnoreCase("DSA") &&
algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) ||
(algName.equalsIgnoreCase("RSA") &&
algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1))) {
return true;
} else {
return false;
}
}
}
For example, if the original XML starts with:
<nfeProc versao="1.10" xmlns="http://www.portalfiscal.inf.br/nfe">
<NFe xmlns="http://www.portalfiscal.inf.br/nfe">
<infNFe Id="NFe31090807301671000131550010001000216008030809" versao="1.10" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...
doc4.asXML() return this:
<nfeProc xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.10">
<NFe>
<infNFe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Id="NFe31090807301671000131550010001000216008030809" versao="1.10">
...
I had a closer look at this, and it turns out that DOM4J DOMWriter is doing something odd w.r.t. namespaces that obviously confuses the canonicalization process. I haven't pin pointed the exact reason, but I think it has to do with DOMWriter inserting extra xmlns attributes in the DOM elements. You can see the effect if you turn on logging for the XML digital signature API (as described in the article you refer to), the canonicalized <SignedInfo> element lacks namespace declaration in the DOM document produced by DOM4J.
However, instead of using DOMWriter, you can produce a DOM document by transformation, using a DOM4J DocumentSource and a DOMResult.
/**
* Create a DOM document from a DOM4J document
*/
static Document copy(org.dom4j.Document orig) {
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
DOMResult result = new DOMResult();
t.transform(new DocumentSource(orig), result);
return (Document) result.getNode();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Using the resulting DOM document, the validation works.
Java, Xerces 2.9.1
insertHere.setAttributeNS(XMLConstants.XML_NS_URI, "xml:space", "preserve");
and
insertHere.setAttributeNS(XMLConstants.XML_NS_URI, "space", "preserve")
both end up with an attribute of just space='preserve', no XML prefix.
insertHere.setAttribute( "xml:space", "preserve")
works, but it seems somehow wrong. Am I missing anything?
EDIT
I checked.
I read a template document in with setNamespaceAware turned on.
I then use the following to make a copy of it, and then I start inserting new elements.
public static Document copyDocument(Document input) {
DocumentType oldDocType = input.getDoctype();
DocumentType newDocType = null;
Document newDoc;
String oldNamespaceUri = input.getDocumentElement().getNamespaceURI();
if (oldDocType != null) {
// cloning doctypes is 'implementation dependent'
String oldDocTypeName = oldDocType.getName();
newDocType = input.getImplementation().createDocumentType(oldDocTypeName,
oldDocType.getPublicId(),
oldDocType.getSystemId());
newDoc = input.getImplementation().createDocument(oldNamespaceUri, oldDocTypeName,
newDocType);
} else {
newDoc = input.getImplementation().createDocument(oldNamespaceUri,
input.getDocumentElement().getNodeName(),
null);
}
Element newDocElement = (Element)newDoc.importNode(input.getDocumentElement(), true);
newDoc.replaceChild(newDocElement, newDoc.getDocumentElement());
return newDoc;
}
When I run the following code:
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class Demo {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.newDocument();
Element rootElement = document.createElement("root");
document.appendChild(rootElement);
rootElement.setAttributeNS(XMLConstants.XML_NS_URI, "space", "preserve");
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.transform(new DOMSource(document), new StreamResult(System.out));
}
}
I get the following output:
<root xml:space="preserve"/>
How are you building your document?