【问题标题】:parse google geocode with xstream使用 xstream 解析谷歌地理编码
【发布时间】:2010-10-28 18:09:28
【问题描述】:

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

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

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

【问题讨论】:

    标签: java geocoding xstream


    【解决方案1】:

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

    这里有一个完整的例子:

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

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

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

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

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

          【讨论】:

          • +1,如果您从 Java 对象开始并让它确定要从它们生成的 XML,XStream 效果最好。 JAXB 是相反的,但可能是矫枉过正。我可能只使用标准的 Java XML DOM 解析器:编写一个方法,使用它将 XML 解析为 DOM 树数据结构,然后遍历树以挑选出创建地址对象所需的信息。跨度>
          • JAXB 可以以对象或 XML 开头。请参阅我的帖子,了解如何使用 MOXy JAXB 扩展轻松映射此用例。
          【解决方案5】:

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

          【讨论】:

          • 我想过。我认为实际上有更好的方法。我现在正在阅读有关转换器的信息。看来我应该能够实现转换器接口并指定一种解析 xml 和设置适当字段的方式。我会发布我的发现。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-09-28
          • 1970-01-01
          • 1970-01-01
          • 2012-05-30
          • 2014-04-06
          • 2011-08-12
          • 1970-01-01
          相关资源
          最近更新 更多