javaapiforkml icon indicating copy to clipboard operation
javaapiforkml copied to clipboard

default namespace is ns3:

Open yaogyao opened this issue 11 years ago • 12 comments

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.

yaogyao avatar Jun 24 '14 15:06 yaogyao

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&lt;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"&gt;}</pre>
     * <p>is changed to:</p>
     * <pre>{@code &lt;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"&gt;}</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;
    }

}

ZiglioUK avatar Jun 24 '14 22:06 ZiglioUK

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");
  ...

ZiglioUK avatar Jun 24 '14 22:06 ZiglioUK

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 "".

tuxBurner avatar Jun 27 '14 10:06 tuxBurner

@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 ?

tuxBurner avatar Jun 27 '14 10:06 tuxBurner

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.

AndrewBartels avatar Jun 03 '15 22:06 AndrewBartels

Still following

ZiglioUK avatar Jun 03 '15 23:06 ZiglioUK

Would a removal of the final declaration of this two classes would solve the issue for you?

unterstein avatar Jun 10 '15 06:06 unterstein

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 .

AndrewBartels avatar Jun 10 '15 07:06 AndrewBartels

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!

polarene avatar Jul 17 '15 15:07 polarene

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.

ZiglioUK avatar Dec 04 '15 02:12 ZiglioUK

Sorry, this project is not actively maintained :pensive:

See #18 for further information.

mischah avatar Feb 21 '16 13:02 mischah

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.

jimmylin avatar May 01 '18 18:05 jimmylin

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"

urbancamo avatar Nov 21 '23 18:11 urbancamo

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.

urbancamo avatar Nov 21 '23 18:11 urbancamo

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

urbancamo avatar Nov 21 '23 18:11 urbancamo

OK this is fixed. Using jakarta allows the default namespace prefix to be defined in package-info.java

urbancamo avatar Nov 21 '23 19:11 urbancamo