Thursday, August 07, 2008

Using JAXB to generate KML Java classes

Some days ago I write a post about using JAXB with the KML's XSD file.
Due to a comment I would like to write more explicitly how I generated the Java files.

First of all, what you need is the XSD files which defines the KML syntax (http://schemas.opengis.net/kml).
Also, you need the xjc utility, included in the JDK6 (or download the JAXB project files).

Uncompress the XSD zip file and go into the uncompressed folder. Execute:
xjc -xmlschema -verbose -extension ogckml22.xsd
and get an error similar to this:

[ERROR] Two declarations cause a collision in the ObjectFactory class.
line 1058 of file:kml_files/ogckml22.xsd

[ERROR] (Related to above error) This is the other declaration.
line 255 of file:kml_files/ogckml22.xsd

[ERROR] Two declarations cause a collision in the ObjectFactory class.
line 350 of file:kml_files/ogckml22.xsd

[ERROR] (Related to above error) This is the other declaration.
line 261 of file:kml_files/ogckml22.xsd


The problem is there are two scale elements defined, one like 'scale' and the other with upper case 'Scale'. And the same for the snippet element.
By default, JAXB uses case insensitive which will produce duplicated class names.

To resolve this there are some solutions. One is to customize the JAXB specifying the class name to be generated for some elements. The later is a workaround (that I used) that consist to change the name for one of the duplicated elements.
In line 255 change:




by




and in line 1391 chage:



by




The same for the snippet element.

Now you can re-execute the xjc command and a set of Java classes will be generated. The only difference is the change in the scale element which produces a different class name.

15 comments:

Anonymous said...

Antonio,

this is great. I followed your instructions and it worked. I have been trying for a long time to get those xsd files to compile without success. Thank a lot for sharing your work. I am new to this and I have one question: in the java code
JAXBContext context = JAXBContext.newInstance("package name");

what is the "package name" I have to use.

Thanks

Antonio Santiago said...

I workingDog and a lot of thanks for your words.
Take a look at doc:
http://java.sun.com/webservices/docs/1.4/tutorial/doc/JAXBWorks2.html#wp82683 and
http://java.sun.com/webservices/docs/1.6/api/javax/xml/bind/JAXBContext.html.

In summary, the context path is the path to the packages than contains the classes generated from an XSD you want to work.

Anonymous said...

I worked it out. I was asking the question because "xjc -xmlschema -verbose -extension ogckml22.xsd" works, but not "xjc -p packagename -xmlschema -verbose -extension ogckml22.xsd" and so I was stuck to determine the package name. But I worked out that using "net.opengis.kml._2" does the trick.

Thanks for your comments.

Anonymous said...

Thanks a lot for sharing your knowledge !
But what if you want to create a KML file from Java Object ? You will get a wrong XML (LiteralScale instead of scale...)

Antonio Santiago said...

Thanks for your comment moks.
You are right. I only was thinking on reading KML but yes, there is a problem if you want to use it to write.
I think the good solution is to customize JAXB.

Anonymous said...

The cleanest solution is to use a separate bindings file to customise the mapping without changing the original schema.

I use the following command:

xjc -d src_generated -b bindings.xjb http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd

with the following bindings.xjb file:


<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <jxb:bindings schemaLocation="http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd" node="/xs:schema">
    <jxb:schemaBindings>
      <jxb:package name="org.my.schema.external.net.opengis.kml" />
    </jxb:schemaBindings>

    <!-- Rename Java names of elements with naming conflicts (elements exist with names "scale", "Scale", "snippet" and "Snippet") -->
    <jxb:bindings node="//xs:element[@name='scale']">
      <jxb:class name="ScaleScalar"/>
    </jxb:bindings>
    <jxb:bindings node="//xs:element[@name='Snippet']">
      <jxb:class name="SnippetDeprecated"/>
    </jxb:bindings>

  </jxb:bindings>


  <jxb:bindings schemaLocation="http://schemas.opengis.net/kml/2.2.0/atom-author-link.xsd" node="/xs:schema">
    <jxb:schemaBindings>
      <jxb:package name="org.my.schema.external.org.w3.atom" />
    </jxb:schemaBindings>
  </jxb:bindings>


  <jxb:bindings schemaLocation="http://docs.oasis-open.org/election/external/xAL.xsd" node="/xs:schema">
    <jxb:schemaBindings>
      <jxb:package name="org.my.schema.external.oasis.names.tc.ciq.xsdschema.xal" />
    </jxb:schemaBindings>
  </jxb:bindings>
</jxb:bindings>


Note that I'm also specifying package names for the generated classes. They are prefixed with my organisation's domain so that there is no possibility that these generated classes will conflict with any official classes that are released by these external organisations in future.

KG said...

To Martin Jericho:
Spot on. I agree that's the best, correct solution.

Anonymous said...

Martin, great work.

After using your suggested xjb file and running the *.java through javadoc, I get a strange API for e.g PlacemarkType. The AbstractFeatureType has a 'rest' list. The javadoc suggests that Snippet/snippet name clash is the culprit, and that a property customization may produce a more intuitive Java API???

Anyone know how to do this?

Anonymous said...

Ah, well, to follow up my own last post, I fleshed out the xjb file to this, for the Snippet/snippet clash:

jxb:class name="SnippetDeprecated"/>
jxb:property name="SnippetDeprecated"/>

and the Java api looks better. I have to concede that I do not fully understand all this ;)

stu

Antonio Santiago said...

Thank you boys for this comment-thread, and thanks for your explanations too.
This is one of the good advantages of the net.

Anonymous said...

Thanks Guys !! This thread help me too...I just successfully generated java code.

Thanks
-Arun

Theo said...

great. I used successfully the xjb proposed but I had to add a third conflict resolution on the element name 'name' (line 239 of the xsd)
Thanks

Anonymous said...

[url=http://kfarbair.com][img]http://www.kfarbair.com/_images/_photos/photo_big7.jpg[/img][/url]

בית מלון [url=http://www.kfarbair.com]כפר בעיר[/url] - שלווה, [url=http://www.kfarbair.com/about.html]חדרים[/url] מרווחים, אינטימיות, [url=http://kfarbair.com/services.html]שקט[/url] . אנחנו מציעים שירותי אירוח מיוחדים כמו כן ישנו במקום שירות חדרים הכולל [url=http://www.kfarbair.com/eng/index.html]אחרוחות רומנטיות[/url] במחירים מיוחדים אשר מוגשות ישירות לחדרכם...

לפרטים נא לפנות לעמוד המלון - [url=http://kfarbair.com]כפר בעיר[/url] [url=http://www.kfarbair.com/contact.html][img]http://www.kfarbair.com/_images/apixel.gif[/img][/url]

free shemale sex stories said...

Whilelicking, his hands moved to her front and into her crotch. She imagined rubbing some cream on hischest, down his navel and then some more on his prickand then slowly lick it all off with very, very slowlicks.
old gay sex stories
free erotic gay sex stories
straitjacket diaper bondage stories
horse sex stories
free lesbian sex stories pictures video
Whilelicking, his hands moved to her front and into her crotch. She imagined rubbing some cream on hischest, down his navel and then some more on his prickand then slowly lick it all off with very, very slowlicks.

adult theater sex stories said...

After about 10minutes I have her cunt as smooth as a babys butt. I was obedientand did what he told me to do and lay on my back and waited forhis penetration.
fictional young adult celebrity sex stories
kid animal sex stories
eu nifty stories
sex stories of incest
femdom fmm stories
After about 10minutes I have her cunt as smooth as a babys butt. I was obedientand did what he told me to do and lay on my back and waited forhis penetration.