将对象映射到多个XML模式–天气示例

我已经在EclipseLink JAXB(MOXy)@XmlPath外部绑定文件扩展中撰写了以前的文章。 在本文中,我将通过将单个对象模型映射到两个不同的XML模式来演示这些扩展的功能。

为了使示例更加“真实”,XML数据将来自提供天气信息的两种不同服务:Google和Yahoo。

Java模型

以下域模型将用于此帖子:

天气预报

package blog.weather;
 
import java.util.List;
 
public class WeatherReport {
 
    private String location;
    private int currentTemperature;
    private String currentCondition;
    private List forecast;
 
}

预测

package blog.weather;
 
public class Forecast {
 
    private String dayOfTheWeek;
    private int low;
    private int high;
    private String condition;
 
}

Google Weather API

首先,我们将利用Google的Weather API。 以下URL将用于访问加拿大渥太华的天气数据:

http://www.google.com/ig/api?weather=渥太华

以下是在我撰写本文时执行上述查询的结果。 我已经突出显示了我们将映射到XML文档的部分:

<xml_api_reply version="1">
    <weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1"
        row="0" section="0">
        <forecast_information>
            <city data="Ottawa, ON" />
            <postal_code data="Ottawa" />
            <latitude_e6 data="" />
            <longitude_e6 data="" />
            <forecast_date data="2011-09-08" />
            <current_date_time data="2011-09-08 14:00:00 +0000" />
            <unit_system data="US" />
        </forecast_information>
        <current_conditions>
            <condition data="Mostly Cloudy" />
            <temp_f data="66" />
            <temp_c data="19" />
            <humidity data="Humidity: 73%" />
            <icon data="/ig/images/weather/mostly_cloudy.gif" />
            <wind_condition data="Wind: NE at 13 mph" />
        </current_conditions>
        <forecast_conditions>
            <day_of_week data="Thu" />
            <low data="55" />
            <high data="75" />
            <icon data="/ig/images/weather/cloudy.gif" />
            <condition data="Cloudy" />
        </forecast_conditions>
        <forecast_conditions>
            <day_of_week data="Fri" />
            <low data="46" />
            <high data="77" />
            <icon data="/ig/images/weather/mostly_sunny.gif" />
            <condition data="Partly Sunny" />
        </forecast_conditions>
        <forecast_conditions>
            <day_of_week data="Sat" />
            <low data="43" />
            <high data="68" />
            <icon data="/ig/images/weather/sunny.gif" />
            <condition data="Clear" />
        </forecast_conditions>
        <forecast_conditions>
            <day_of_week data="Sun" />
            <low data="55" />
            <high data="75" />
            <icon data="/ig/images/weather/sunny.gif" />
            <condition data="Clear" />
        </forecast_conditions>
    </weather>
</xml_api_reply>

Java模型-通过注释映射到Google的XML模式

我们将通过标准JAXB和MOXy扩展注释的组合来映射Google weather API的结果。

天气预报

package blog.weather;
 
import java.util.List;
 
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
 
import org.eclipse.persistence.oxm.annotations.XmlPath;
 
@XmlRootElement(name="xml_api_reply")
@XmlType(propOrder={"location", "currentCondition", "currentTemperature", "forecast"})
@XmlAccessorType(XmlAccessType.FIELD)
public class WeatherReport {
 
    @XmlPath("weather/forecast_information/city/@data")
    private String location;
 
    @XmlPath("weather/current_conditions/temp_f/@data")
    private int currentTemperature;
 
    @XmlPath("weather/current_conditions/condition/@data")
    private String currentCondition;
 
    @XmlPath("weather/forecast_conditions")
    private List<Forecast> forecast;
 
}

预测

package blog.weather;
 
import org.eclipse.persistence.oxm.annotations.XmlPath;
 
public class Forecast {
 
    @XmlPath("day_of_week/@data")
    private String dayOfTheWeek;
 
    @XmlPath("low/@data")
    private int low;
 
    @XmlPath("high/@data")
    private int high;
 
    @XmlPath("condition/@data")
    private String condition;
 
}

演示版

以下演示代码将读取Google气象服务的XML数据,并将对象编组回XML:

package blog.weather;
 
import java.net.URL;
import javax.xml.bind.*;
 
public class GoogleDemo {
 
    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(WeatherReport.class);
 
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        URL url = new URL("http://www.google.com/ig/api?weather=Ottawa");
        WeatherReport weatherReport = (WeatherReport) unmarshaller.unmarshal(url);
 
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(weatherReport, System.out);
    }
 
}

输出量

以下是运行演示代码的结果。 输出代表我们映射到的XML文档的一部分:

<?xml version="1.0" encoding="UTF-8"?>
<xml_api_reply>
   <weather>
      <forecast_information>
         <city data="Ottawa, ON"/>
      </forecast_information>
      <current_conditions>
         <condition data="Mostly Cloudy"/>
         <temp_f data="68"/>
      </current_conditions>
      <forecast_conditions>
         <day_of_week data="Thu"/>
         <low data="55"/>
         <high data="75"/>
         <condition data="Cloudy"/>
      </forecast_conditions>
      <forecast_conditions>
         <day_of_week data="Fri"/>
         <low data="46"/>
         <high data="77"/>
         <condition data="Partly Sunny"/>
      </forecast_conditions>
      <forecast_conditions>
         <day_of_week data="Sat"/>
         <low data="43"/>
         <high data="68"/>
         <condition data="Clear"/>
      </forecast_conditions>
      <forecast_conditions>
         <day_of_week data="Sun"/>
         <low data="55"/>
         <high data="75"/>
         <condition data="Clear"/>
      </forecast_conditions>
   </weather>
</xml_api_reply>

雅虎天气API

以下URL将用于使用Yahoo Weather API(3369是渥太华的WOEID)访问渥太华的天气数据:

http://weather.yahooapis.com/forecastrss?w=3369

以下是在我撰写本文时执行上述查询的结果:

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"
    xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
    <channel>
        <title>Yahoo! Weather - Ottawa, CA</title>
        <link>http://us.rd.yahoo.com/dailynews/rss/weather/Ottawa__CA/*http://weather.yahoo.com/forecast/CAXX0343_f.html</link>
        <description>Yahoo! Weather for Ottawa, CA</description>
        <language>en-us</language>
        <lastBuildDate>Thu, 08 Sep 2011 10:58 am EDT</lastBuildDate>
        <ttl>60</ttl>
        <yweather:location city="Ottawa" region="ON"
            country="Canada" />
        <yweather:units temperature="F" distance="mi" pressure="in"
            speed="mph" />
        <yweather:wind chill="66" direction="40" speed="12" />
        <yweather:atmosphere humidity="73" visibility=""
            pressure="30.14" rising="0" />
        <yweather:astronomy sunrise="6:31 am" sunset="7:25 pm" />
        <image>
            <title>Yahoo! Weather</title>
            <width>142</width>
            <height>18</height>
            <link>http://weather.yahoo.com</link>
            <url>http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif</url>
        </image>
        <item>
            <title>Conditions for Ottawa, CA at 10:58 am EDT</title>
            <geo:lat>45.42</geo:lat>
            <geo:long>-75.69</geo:long>
            <link>http://us.rd.yahoo.com/dailynews/rss/weather/Ottawa__CA/*http://weather.yahoo.com/forecast/CAXX0343_f.html</link>
            <pubDate>Thu, 08 Sep 2011 10:58 am EDT</pubDate>
            <yweather:condition text="Mostly Cloudy" code="28"
                temp="66" date="Thu, 08 Sep 2011 10:58 am EDT" />
            <description><![CDATA[
<img src="http://l.yimg.com/a/i/us/we/52/28.gif"/>
 
<b>Current Conditions:</b>
 
Mostly Cloudy, 66 F
 
 
<b>Forecast:</b>
 
Thu - Partly Cloudy. High: 75 Low: 57
 
Fri - Partly Cloudy. High: 79 Low: 53
 
 
 
<a href="http://us.rd.yahoo.com/dailynews/rss/weather/Ottawa__CA/*http://weather.yahoo.com/forecast/CAXX0343_f.html">Full Forecast at Yahoo! Weather</a>
 
 
(provided by <a href="http://www.weather.com" >The Weather Channel</a>)
 
]]></description>
            <yweather:forecast day="Thu" date="8 Sep 2011" low="57"
                high="75" text="Partly Cloudy" code="30" />
            <yweather:forecast day="Fri" date="9 Sep 2011" low="53"
                high="79" text="Partly Cloudy" code="30" />
            <guid isPermaLink="false">CAXX0343_2011_09_09_7_00_EDT</guid>
        </item>
    </channel>
</rss><!-- api4.weather.sp2.yahoo.com uncompressed/chunked Thu Sep 8 08:32:54
    PDT 2011 -->

Java模型–通过XML元数据映射到Yahoo的XML模式

由于我们无法通过注释提供到对象模型的第二套映射,因此我们必须利用MOXy的XML元数据提供后续的映射。 默认情况下,MOXy的映射文档用于补充模型上指定的所有注释。 但是,如果设置了xml-mapping-metadata-complete标志,则XML元数据将完全替换注释提供的元数据(用于Google映射的注释将保留在POJO上,但是xml-mapping-metadata-complete标志告诉MOXy忽略它们)。

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="blog.weather"
    xml-mapping-metadata-complete="true">
    <xml-schema element-form-default="QUALIFIED">
        <xml-ns prefix="yweather" namespace-uri="http://xml.weather.yahoo.com/ns/rss/1.0"/>
    </xml-schema>
    <java-types>
        <java-type name="WeatherReport" xml-accessor-type="FIELD">
            <xml-root-element name="rss"/>
            <xml-type prop-order="location currentTemperature currentCondition forecast"/>
            <java-attributes>
                <xml-attribute java-attribute="location" xml-path="channel/yweather:location/@city"/>
                <xml-attribute java-attribute="currentTemperature" name="channel/item/yweather:condition/@temp"/>
                <xml-attribute java-attribute="currentCondition" name="channel/item/yweather:condition/@text"/>
                <xml-element java-attribute="forecast" name="channel/item/yweather:forecast"/>
            </java-attributes>
        </java-type>
        <java-type name="Forecast" xml-accessor-type="FIELD">
            <java-attributes>
                <xml-attribute java-attribute="dayOfTheWeek" name="day"/>
                <xml-attribute java-attribute="low"/>
                <xml-attribute java-attribute="high"/>
                <xml-attribute java-attribute="condition" name="text"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

演示版

以下演示代码将读取Yahoo气象服务的XML数据,并将对象编组回XML。 由于与未映射的CDATA部分有关的MOXy错误(https://bugs.eclipse.org/357145),使用了经过过滤的XMLStreamReader将其从XML输入中删除:

package blog.weather;
 
import java.util.HashMap;
import java.util.Map;
 
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.StreamFilter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stream.StreamSource;
 
import org.eclipse.persistence.jaxb.JAXBContextFactory;
 
public class YahooDemo {
 
    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>(1);
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "blog/weather/yahoo-binding.xml");
        JAXBContext jc = JAXBContext.newInstance(new Class[] {WeatherReport.class}, properties);
 
        XMLInputFactory xif = XMLInputFactory.newFactory();
        StreamSource xml = new StreamSource("http://weather.yahooapis.com/forecastrss?w=3369");
        XMLStreamReader xsr = xif.createXMLStreamReader(xml);
        xsr = xif.createFilteredReader(xsr, new CDATAFilter());
 
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        WeatherReport weatherReport = (WeatherReport) unmarshaller.unmarshal(xsr);
 
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(weatherReport, System.out);
    }
 
    private static class CDATAFilter implements StreamFilter {
 
        public boolean accept(XMLStreamReader xsr) {
            return XMLStreamReader.CDATA != xsr.getEventType();
        }
 
    }
 
}

输出量

以下是运行演示代码的结果。 输出代表我们映射到的XML文档的一部分:

<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0">
   <channel>
      <yweather:location city="Ottawa"/>
      <item>
         <yweather:forecast day="Thu" low="57" high="74" text="Partly Cloudy"/>
         <yweather:forecast day="Fri" low="53" high="79" text="Partly Cloudy"/>
      </item>
   </channel>
</rss>

参考: Java XML和JSON绑定博客上的 JCG合作伙伴 Blaise Doughan的参考:将 对象映射到多个XML模式-天气示例

相关文章 :


翻译自: https://www.javacodegeeks.com/2011/09/mapping-objects-to-multiple-xml-schemas.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值