2

我正在使用 Java 和 XStream 通过 http 解析谷歌地理编码请求。我的想法是拥有一个包含所有地理编码属性(即纬度/经度、城市、省/州等)的地址类,但我在使用 xstream 解析 xml 时遇到问题。

谷歌的回应与此类似:

<?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.country = blah)地址对象将非常简单,主要只是国家的字符串名称等并浮动纬度/经度。

文档和示例仅显示直接映射,其中每个 xml 标记直接映射到对象的同名属性。但是,在我的情况下,标签的名称与对象 attr 的名称不同。一个正确方向的快速点是我真正想要的。

4

5 回答 5

2

我在几个项目中使用过 XStream。不幸的是,您的问题并不是 XStream 旨在解决的问题。您也许可以使用它的转换器机制来实现您的直接目标,但您会遇到限制。简而言之,XStream 的设计目的不是将树结构 A 转换为树结构 B——它的目的是将 Java 域模型转换为一些合理的 XML。当您不太关心生成的 XML 的细节时,XStream 是一个很好的工具。如果您更关心 XML 而不是 Java 对象,请查看 XMLBeans——Java 很丑陋,但它非常符合模式。

对于您的项目,我将通过 XML bean 运行 Google XML 模式,生成一些 Java,这将为您提供一种更熟练的手动编码转换器的方式。您可以使用原始 DOM 树,但您将拥有类似 myAddress.setStreet(root.getFirstChild().getAttribute("addr1"))) 的代码。对于 XML bean,您可以说类似 myAddress.setStreet(googleResult.getAddress().getStreetName();

我会忽略 JAXB,因为它试图将接口与实现分开会增加不必要的复杂性。Castor 可能也是一个值得考虑的好工具,但我已经很多年没有使用它了。

简而言之,没有很多好的对象到对象或 XML 到对象的转换器可以很好地处理结构转换。在我见过的尝试声明性解决方案的那些方案中,所有这些方案似乎都比使用 XStream/XmlBeans 和手动编码的结构转换复杂得多(并且更难维护)。

于 2009-06-01T00:12:03.153 回答
0

是否可以定义一个专门用于处理 XStream 映射的单独类?AddressDetails然后,您可以通过从其他对象中查询值来简单地填充您的对象。

于 2009-05-25T14:39:32.240 回答
0

我最终只使用 xpath 并手动填充我自己的地址对象。似乎工作正常。

于 2009-06-29T16:00:14.590 回答
0

你试过json格式吗?它应该是相同的,但您需要将 com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver 设置为 XStream 的驱动程序

于 2009-07-19T18:46:01.647 回答
0

您可以使用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; 

此处提供了完整示例:

于 2010-07-21T19:06:26.803 回答