javaapiforkml
javaapiforkml copied to clipboard
default namespace is ns3:
I used this jar to generate kml, but the default namespace is "ns3:" which is quite annoying.
<ns3:kml xmlns:xal="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:ns3="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
I extended the Kml class to override the NameSpaceBeautyfier. add this: if (namespaceUri.matches("http://www.opengis.net/kml/.*?")) { return ""; }
now it output kml without ns3 but default. The difference is "" will be used as default namespace, while "null" will generate some namespace (e.g. ns3:).
it will be great if you can update your code in github so I don't need to extend your class but use it directly.
I haven't touched it for a while but like you I once solved this problem using a NamespaceBeautifier.
private final static class NameSpaceBeautyfier
extends NamespacePrefixMapper
{
/**
* Internal method!
* <p>Customizing Namespace Prefixes During Marshalling to a more readable format.</p>
* <p>The default output is like:</p>
* <pre>{@code<kml ... xmlns:ns2="http://www.w3.org/2005/Atom" xmlns:ns3="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0" xmlns:ns4="http://www.google.com/kml/ext/2.2">}</pre>
* <p>is changed to:</p>
* <pre>{@code <kml ... xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xal="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0" xmlns:gx="http://www.google.com/kml/ext/2.2">}</pre><p>What it does:</p>
* <p>namespaceUri: http://www.w3.org/2005/Atom prefix: atom</p><p>namespaceUri: urn:oasis:names:tc:ciq:xsdschema:xAL:2.0 prefix: xal</p><p>namespaceUri: http://www.google.com/kml/ext/2.2 prefix: gx</p><p>namespaceUri: anything else prefix: null</p>
*
*/
@Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
if (namespaceUri.matches("http://www.w3.org/\\d{4}/Atom")) {
return "atom";
}
if (namespaceUri.matches("urn:oasis:names:tc:ciq:xsdschema:xAL:.*?")) {
return "xal";
}
if (namespaceUri.matches("http://www.google.com/kml/ext/.*?")) {
return "gx";
}
return null;
}
}
Currently, for memory reasons, I've switched to using a XMLStreamWriter, so I do
XMLStreamWriter xmlOut = XMLOutputFactory.newInstance().createXMLStreamWriter(sw);
xmlOut.writeStartDocument("UTF-8", "1.0");
xmlOut.writeStartElement("kml");
xmlOut.writeDefaultNamespace("http://www.opengis.net/kml/2.2");
xmlOut.writeNamespace("atom", "http://www.w3.org/2005/Atom");
xmlOut.writeNamespace("kml", "http://www.opengis.net/kml/2.2");
xmlOut.writeNamespace("gx", "http://www.google.com/kml/ext/2.2");
xmlOut.writeNamespace("xal", "urn:oasis:names:tc:ciq:xsdschema:xAL:2.0");
xmlOut.writeStartElement("Document");
...
Hi @yaogyao,
i found this in de.micromata.jak.NameSpaceBeautyfier#getPreferredPrefix outcomment:
//if (namespaceUri.matches("http://www.opengis.net/kml/.*?")) { // return "kml"; //}
i can comment this in again and make it return "".
@yaogyao, oh sorry should have read that you extend: de.micromata.opengis.kml.v_2_2_0.Kml#Kml I am not sure if we change the namespace if it will break other peoples stuff using this :) Any ideas if it is safe to do so as @yaogyao suggested ?
Yeah, guys the issue he is bringing up is a real problem. The both the Kml and NameSpaceBeautyfier classes are declared final, so no one can extend from or override them. I'm having to download the source code and include it with my project, along with the change, in order to get rid of the "ns2:" problem.
Still following
Would a removal of the final declaration of this two classes would solve the issue for you?
Yes, that would be ideal. I'd like to extend them and modify some of the behavior to be better suited for this application.
Thank you, this would be awesome!
-Andrew
On Tue, Jun 9, 2015 at 11:07 PM, Johannes Unterstein < [email protected]> wrote:
Would a removal of the final declaration of this two classes would solve the issue for you?
— Reply to this email directly or view it on GitHub https://github.com/micromata/javaapiforkml/issues/5#issuecomment-110604143 .
This problem is very annoying and was cause of frustration, since the generated output without the default kml namespace ("ns3" in my case) isn't accepted by google maps file import.
I don't think making the inner class NameSpaceBeautyfier extendable would make any difference since the marshaller setup happens in createMarshaller(), where it's created as
new Kml.NameSpaceBeautyfier()
thus rendering a local type extension useless. But createMarshaller() is declared private anyway, so there's no extension possible apart from recreating the marshaller by hand outside Kml and set your version of NameSpaceBeautyfier or including the entire modified source as Andrew sugggested.
So, if you can't change the namespace generation in the lib, at least make createMarshaller() protected so it can be overridden. Thanks for your support!
I've done some work on namespaces, can you check this answer http://stackoverflow.com/questions/31358331/java-api-for-kml-jak-removing-extra-ns2-annotation-in-kml/34079857#34079857
The results uses the kml prefix, it can be removed I believe by defining a NamespacePrefixMapper that returns "" instead of null.
Sorry, this project is not actively maintained :pensive:
See #18 for further information.
Laubfall, is there a plan to work on these in the near future? I have confirmed that the kmls generated using this library does not work with ArcGIS Portal (a web based mapping platform). I am starting to believe that all of these web based mapping platforms (Google Maps, Google MyMaps) are using a third party library that is not OGC compliant in terms of accepting the kml namespace prefix.
Just rechecked this and I believe it is working as intended, with no issues importing into Google Earth:
xmlns:kml="http://www.opengis.net/kml/2.2"
Re-opened. I had dealt with this issue within my own code with the following:
private void replaceNameSpaces(String inPath, String outPath, TransformResults results) {
try (
BufferedWriter writer = Files.newBufferedWriter(Path.of(outPath), StandardCharsets.UTF_8);
BufferedReader reader = Files.newBufferedReader(Path.of(inPath), StandardCharsets.UTF_8);) {
while (reader.ready()) {
String line = reader.readLine();
String newLine = line.replaceAll("ns2:", "").replace("<kml xmlns:ns2=\"http://www.opengis.net/kml/2.2\" xmlns:ns3=\"http://www.w3.org/2005/Atom\" xmlns:ns4=\"urn:oasis:names:tc:ciq:xsdschema:xAL:2.0\" xmlns:ns5=\"http://www.google.com/kml/ext/2.2\">", "<kml>");
writer.write(newLine);
}
} catch (IOException e) {
results.setError(e.getMessage());
e.printStackTrace();
}
}
definitely not an optimal solution, so will continue to investigate the comments above and alternatives.
I don't want to use XSL, as it brings me out in hives, but it would provide a solution independent of any previously undesirable dependencies, see: https://stackoverflow.com/questions/10124887/how-to-replace-namespace-prefix-in-element-and-attributes-using-xslt
OK this is fixed. Using jakarta allows the default namespace prefix to be defined in package-info.java