Чтобы сделать пример более «реальным», данные XML будут поступать из двух разных служб, предоставляющих информацию о погоде: Google и Yahoo.
Модель Java
Для этого поста будет использоваться следующая модель домена:
Прогноз погоды
|
01
02
03
04
05
06
07
08
09
10
11
12
|
package blog.weather; import java.util.List; public class WeatherReport { private String location; private int currentTemperature; private String currentCondition; private List forecast; } |
Прогноз
|
01
02
03
04
05
06
07
08
09
10
|
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=Ottawa
Ниже приведен результат выполнения вышеуказанного запроса в то время, когда я писал эту статью. Я выделил части документа XML, на которые мы будем отображать:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
<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 — сопоставлена с XML-схемой Google с помощью аннотаций
Мы отобразим результат API погоды Google с помощью комбинации стандартных аннотаций расширений JAXB и MOXy.
Прогноз погоды
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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; } |
Прогноз
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
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; } |
демонстрация
Следующий демонстрационный код будет читать данные XML для службы погоды Google и перенаправлять объекты обратно в XML:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
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(); WeatherReport weatherReport = (WeatherReport) unmarshaller.unmarshal(url); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(weatherReport, System.out); } } |
Выход
Ниже приведен результат запуска демонстрационного кода. Выходные данные представляют часть XML-документа, который мы сопоставили:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
<?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> |
Yahoo Weather API
Следующий URL-адрес будет использоваться для доступа к данным о погоде для Оттавы с помощью API погоды Yahoo (3369 — это WOEID для Оттавы):
http://weather.yahooapis.com/forecastrss?w=3369
Ниже приведен результат выполнения вышеуказанного запроса в то время, когда я писал эту статью:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
<?xml version="1.0" encoding="UTF-8"?> <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> </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 говорит МОКСИ игнорировать их).
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<?xml version="1.0"?><xml-bindings package-name="blog.weather" xml-mapping-metadata-complete="true"> <xml-schema element-form-default="QUALIFIED"> </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> |
демонстрация
В следующем демонстрационном коде будут прочитаны данные XML для службы погоды Yahoo и перенаправлены объекты обратно в XML. Из-за ошибки MOXy, связанной с несопоставленными разделами CDATA (https://bugs.eclipse.org/357145), для удаления его из XML-ввода использовался отфильтрованный XMLStreamReader:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
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(); 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-документа, который мы сопоставили:
|
01
02
03
04
05
06
07
08
09
10
|
<?xml version="1.0" encoding="UTF-8"?> <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> |
Ссылка: сопоставление объектов с несколькими XML-схемами — пример погоды от нашего партнера по JCG Блейза Дафана из блога Java XML & JSON Binding .
Статьи по Теме :