разобрать гугл геокод с xstream - PullRequest
2 голосов
/ 25 мая 2009

Я использую Java и XStream для анализа запроса геокодирования Google по http. Моя идея состоит в том, чтобы иметь класс Address со всеми атрибутами геокода (т. Е. Lat / long, city, provice / state и т. Д.), Но у меня возникают проблемы при разборе xml с xstream.

Ответ Google похож на этот:

<?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0"><Response>
  <name>98 St. Patrick St, Toronto</name>
  <Status>
    <code>200</code>
    <request>geocode</request>
  </Status>
  <Placemark id="p1">
    <address>98 St Patrick St, Toronto, ON, Canada</address>
    <AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"> <Country><CountryNameCode>CA</CountryNameCode><CountryName>Canada</CountryName><AdministrativeArea><AdministrativeAreaName>ON</AdministrativeAreaName><Locality><LocalityName>Toronto</LocalityName><Thoroughfare><ThoroughfareName>98 St Patrick St</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>M5T</PostalCodeNumber></PostalCode></Locality></AdministrativeArea></Country></AddressDetails>
    <ExtendedData>
      <LatLonBox north="43.6560378" south="43.6497426" east="-79.3864912" west="-79.3927864" />
    </ExtendedData>
    <Point><coordinates>-79.3896388,43.6528902,0</coordinates></Point>
  </Placemark>
</Response></kml>

Это не очень хорошо видно, но основная часть кода находится в теге AddressDetails.

В любом случае, я новичок в Java и XStream, поэтому терминология API меня немного смущает. Мне просто нужно иметь возможность написать какой-то маппер, который отображает все эти теги (например, CountryName) на атрибут в моем объекте Address (т.е. address.country = blah). Адресный объект будет довольно простым, в основном это просто строки для страны имя и т. д. и плавает на лат / лонг.

В документах и ​​примере просто показано прямое сопоставление, где каждый тег xml отображается непосредственно на атрибут с тем же именем объекта. В моем случае, однако, теги названы иначе, чем объект attr. Быстрая точка в правильном направлении - это все, что я действительно ищу.

Ответы [ 5 ]

2 голосов
/ 01 июня 2009

Я использовал XStream в нескольких проектах. К сожалению, ваша проблема не совсем в том, для чего предназначен XStream. Возможно, вы сможете использовать его механизм преобразования для достижения вашей непосредственной цели, но вы столкнетесь с ограничениями. Короче говоря, XStream не предназначен для преобразования древовидной структуры A в древовидную структуру B - его целью является преобразование модели домена Java в некоторый разумный XML. XStream - это отличный инструмент, когда вас мало заботят детали созданного XML. Если вы заботитесь о XML больше, чем об объектах Java, посмотрите на XMLBeans - Java уродлива, но невероятно совместима со схемой.

Для вашего проекта я бы запустил схему Google XML через XML-компоненты, сгенерировал бы Java, который даст вам более грамотный способ написания кода конвертера вручную. Вы можете использовать необработанное дерево DOM, но у вас будет такой код, как myAddress.setStreet (root.getFirstChild (). GetAttribute ("addr1"))). С XML-бинами вы говорите что-то вроде myAddress.setStreet (googleResult.getAddress (). GetStreetName ();

Я бы проигнорировал JAXB, поскольку его попытка отделить интерфейс от реализации добавляет ненужную сложность. Кастор может быть хорошим инструментом для рассмотрения, но я не использовал его годами.

Короче говоря, не так много хороших преобразователей объект-объект или XML-объект, которые бы хорошо обрабатывали преобразование структуры. Из тех, что я видел в этой попытке декларативных решений, все они казались намного более сложными (и не более легкими в обслуживании), чем использование XStream / XmlBeans вместе с преобразованиями структур, написанными вручную.

0 голосов
/ 21 июля 2010

Вы можете использовать EclipseLink JAXB (MOXy) , чтобы сделать это:

package com.example;

import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement(name="kml")
public class Address {

    private String country;

    @XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:CountryName/text()")
    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

}

и

@javax.xml.bind.annotation.XmlSchema( 
   namespace = "http://earth.google.com/kml/2.0",
   xmlns = { 
      @javax.xml.bind.annotation.XmlNs(
         prefix = "ns", namespaceURI ="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0")
   },
   elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) 
package com.example; 

Полный пример доступен здесь:

0 голосов
/ 19 июля 2009

Вы пробовали в формате json? Это должно быть то же самое, но вам нужно установить com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver в качестве драйвера для XStream

0 голосов
/ 29 июня 2009

Я просто использовал xpath и заполнил свой собственный адресный объект вручную. Кажется, работает нормально.

0 голосов
/ 25 мая 2009

Можно ли определить отдельный класс специально для работы с отображением XStream? Затем вы можете просто заполнить ваш AddressDetails объект, запросив значения у этого другого объекта.

...