You can try this out now using a download available from:
XML Input
Below is the link we will use to get the data as XML. This is specified in the output parameter.
Result
<?xml version="1.0" encoding="UTF-8" ?> <kml xmlns="http://earth.google.com/kml/2.0"> <Response> <name>1600 Amphitheatre Parkway, Mountain View, CA</name> <Status> <code>200</code> <request>geocode</request> </Status> <Placemark id="p1"> <address>1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA </address> <AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"> <Country> <CountryNameCode>US</CountryNameCode> <CountryName>USA</CountryName> <AdministrativeArea> <AdministrativeAreaName>CA</AdministrativeAreaName> <Locality> <LocalityName>Mountain View</LocalityName> <Thoroughfare> <ThoroughfareName>1600 Amphitheatre Pkwy</ThoroughfareName> </Thoroughfare> <PostalCode> <PostalCodeNumber>94043</PostalCodeNumber> </PostalCode> </Locality> </AdministrativeArea> </Country> </AddressDetails> <ExtendedData> <LatLonBox north="37.4227454" south="37.4200474" east="-122.0843863" west="-122.0870843" /> </ExtendedData> <Point> <coordinates>-122.0857353,37.4213964,0</coordinates> </Point> </Placemark> </Response> </kml>
JSON Input
Below is the link we will use to get the data as JSON. This is specified in the output parameter.
Result
{ "name": "1600 Amphitheatre Parkway, Mountain View, CA", "Status": { "code": 200, "request": "geocode" }, "Placemark": [ { "id": "p1", "address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA", "AddressDetails": { "Accuracy" : 8, "Country" : { "AdministrativeArea" : { "AdministrativeAreaName" : "CA", "Locality" : { "LocalityName" : "Mountain View", "PostalCode" : { "PostalCodeNumber" : "94043" }, "Thoroughfare" : { "ThoroughfareName" : "1600 Amphitheatre Pkwy" } } }, "CountryName" : "USA", "CountryNameCode" : "US" } }, "ExtendedData": { "LatLonBox": { "north": 37.4227454, "south": 37.4200474, "east": -122.0843863, "west": -122.0870843 } }, "Point": { "coordinates": [ -122.0857353, 37.4213964, 0 ] } } ] }
Domain Model
The following domain model will be used for this example. Note that the exact same class with the exact same metadata will be used for both the XML and JSON bindings.
Address
package blog.geocode.json; import javax.xml.bind.annotation.XmlType; import org.eclipse.persistence.oxm.annotations.XmlPath; @XmlType(propOrder={"country", "state", "city", "street", "postalCode"}) public class Address { @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:Locality/ns:Thoroughfare/ns:ThoroughfareName/text()") private String street; @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:Locality/ns:LocalityName/text()") private String city; @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:AdministrativeAreaName/text()") private String state; @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:CountryNameCode/text()") private String country; @XmlPath("Placemark/ns:AddressDetails/ns:Country/ns:AdministrativeArea/ns:Locality/ns:PostalCode/ns:PostalCodeNumber/text()") private String postalCode; }
package-info
The @XmlSchema annotation is used to configure the namespace information. These namespaces will be ignored when the JSON binding is performed.
@XmlSchema( namespace="http://earth.google.com/kml/2.0", elementFormDefault=XmlNsForm.QUALIFIED, xmlns={ @XmlNs(prefix="ns", namespaceURI="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0") } ) @XmlAccessorType(XmlAccessType.FIELD) package blog.geocode.json; import javax.xml.bind.annotation.XmlAccessorType;
Demo
The following code will be used to convert the XML and JSON messages to/from objects. Somethings to note about this code:
- Only one JAXBContext is created, this means only one set of initialized metadata.
- Only Java SE 6 imports are required.
- The same instances of Marshaller and Unmarshaller are used for both the XML and JSON binding. JSON binding was enabled by setting the "eclipselink.media.type" property to "application/json" (lines 25 and 29). We also set the "eclipselink.json.include-root" property to false to indicate there is no root node (lines 26 and 30).
- A StAX parser is used to navigate to a local root that is comparable with the JSON structure.
package package blog.geocode.json; import javax.xml.bind.*; import javax.xml.stream.*; import javax.xml.transform.stream.StreamSource; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Address.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // XML XMLInputFactory xif = XMLInputFactory.newInstance(); StreamSource xml = new StreamSource("http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=xml&sensor=false&key=YOUR_KEY_HERE"); XMLStreamReader xsr = xif.createXMLStreamReader(xml); xsr.nextTag(); // Advance to kml tag xsr.nextTag(); // Advance to Response tag JAXBElement<Address> addressFromXML = unmarshaller.unmarshal(xsr, Address.class); marshaller.marshal(addressFromXML, System.out); // JSON unmarshaller.setProperty("eclipselink.media-type", "application/json"); unmarshaller.setProperty("eclipselink.json.include-root", false); StreamSource json = new StreamSource("http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=json&sensor=false&key=YOUR_KEY_HERE"); JAXBElement<Address> addressFromJSON = unmarshaller.unmarshal(json, Address.class); marshaller.setProperty("eclipselink.media-type", "application/json"); marshaller.setProperty("eclipselink.json.include-root", false); marshaller.marshal(addressFromJSON, System.out); } }
XML Output
<?xml version="1.0" encoding="UTF-8"?> <Response xmlns="http://earth.google.com/kml/2.0" xmlns:ns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"> <Placemark> <ns:AddressDetails> <ns:Country> <ns:CountryNameCode>US</ns:CountryNameCode> <ns:AdministrativeArea> <ns:AdministrativeAreaName>CA</ns:AdministrativeAreaName> <ns:Locality> <ns:LocalityName>Mountain View</ns:LocalityName> <ns:Thoroughfare> <ns:ThoroughfareName>1600 Amphitheatre Pkwy</ns:ThoroughfareName> </ns:Thoroughfare> <ns:PostalCode> <ns:PostalCodeNumber>94043</ns:PostalCodeNumber> </ns:PostalCode> </ns:Locality> </ns:AdministrativeArea> </ns:Country> </ns:AddressDetails> </Placemark> </Response>
JSON Output
{ "Placemark" : { "AddressDetails" : { "Country" : { "CountryNameCode" : "US", "AdministrativeArea" : { "AdministrativeAreaName" : "CA", "Locality" : { "LocalityName" : "Mountain View", "Thoroughfare" : { "ThoroughfareName" : "1600 Amphitheatre Pkwy" }, "PostalCode" : { "PostalCodeNumber" : "94043" } } } } } }}
Download the Source Code
The source code for this post is hosted on GitHub here. You can download the source as a zip file here.
Further Reading
If you enjoyed this post, then you may also be interested in:
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.