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
xml对象映射