我想将XML文件解析为该对象。我读了一些文章,教程,我认为在这种情况下最好的选择是JAXB。
XML示例:
<response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XML-Schema-instance" version="1.2" xsi:noNamespaceSchemaLocation="http://aviationweather.gov/adds/schema/metar1_2.xsd">
<request_index>136291043</request_index>
<data_source name="metars"/>
<request type="retrieve"/>
<errors/>
<warnings/>
<time_taken_ms>5</time_taken_ms>
<data num_results="2">
<METAR>
<raw_text>
PHTO 071453Z AUTO 23005KT 10SM FEW060 19/17 A3004 RMK AO2 SLP171 T01940172 55001 TSNO
</raw_text>
<station_id>PHTO</station_id>
<observation_time>2017-07-07T14:53:00Z</observation_time>
<latitude>19.72</latitude>
<longitude>-155.05</longitude>
<temp_c>19.4</temp_c>
<dewpoint_c>17.2</dewpoint_c>
<wind_dir_degrees>230</wind_dir_degrees>
<wind_speed_kt>5</wind_speed_kt>
<visibility_statute_mi>10.0</visibility_statute_mi>
<altim_in_hg>30.041338</altim_in_hg>
<sea_level_pressure_mb>1017.1</sea_level_pressure_mb>
<quality_control_flags>
<auto>TRUE</auto>
<auto_station>TRUE</auto_station>
<lightning_sensor_off>TRUE</lightning_sensor_off>
</quality_control_flags>
<sky_condition sky_cover="FEW" cloud_base_ft_agl="6000"/>
<flight_category>VFR</flight_category>
<three_hr_pressure_tendency_mb>-0.1</three_hr_pressure_tendency_mb>
<metar_type>METAR</metar_type>
<elevation_m>12.0</elevation_m>
</METAR>
<METAR>...</METAR>
</data>
</response>
我创建了DTO课程:
1)数据类:
@XmlRootElement(name = "data")
@XmlAccessorType(XmlAccessType.FIELD)
public class Data {
public Data(){}
public Data(int numResult, List<Metar> metars) {
this.numResult = numResult;
this.metars = metars;
}
public int getNumResult() {
return numResult;
}
public void setNumResult(int numResult) {
this.numResult = numResult;
}
public List<Metar> getMetars() {
return metars;
}
public void setMetars(List<Metar> metars) {
this.metars = metars;
}
@XmlAttribute(name="num_results")
private int numResult;
@XmlElement(name = "METAR")
private List<Metar> metars ;
}
}
2)Metar课程:
@Data
@Builder
@XmlRootElement(name ="METAR")
@XmlAccessorType(XmlAccessType.FIELD)
public class Metar {
@Tolerate
public Metar(){
}
@XmlElement(name = "raw_text")
private String rawText;
@XmlElement(name = "station_id")
private String stationId;
@XmlElement(name = "observation_time")
private String observationTime;
@XmlElement(name = "latitude")
private float latitude;
@XmlElement(name = "longitude")
private float longitude;
@XmlElement(name = "temp_c")
private float tempC; // in decimal Celcius degrees
@XmlElement(name = "dewpoint_c")
private float dewpointC; // in decimal Celcius degrees
@XmlElement(name = "wind_dir_degrees")
private int windDirection; // Degrees
@XmlElement(name = "wind_speed_kt")
private int windSpeed; // Knots
@XmlElement(name = "wind_gust_kt")
private int windGusts; // Knots
@XmlElement(name = "visibility_statute_mi")
private float visibility; // StatuteMiles
@XmlElement(name = "altim_in_hg")
private float altimeter; // inches of Hg
@XmlElement(name = "sea_level_pressure_mb")
private float seaLvlPressure; // mb
@XmlElement(name = "quality_control_flags")
private String qualityControlFlags;
@XmlElement(name = "wx_string")
private String wxString;
等等......超过30个领域。
最后一节用JAXB:
String urlForMetar = StaticValues.MAIN_URL_ADDRESS_FOR_METAR;
private StringBuilder xmlFile;
@Override
public String takeXmlFromApi() throws MalformedURLException, FileNotFoundException {
String line = null;
URL url = new URL(urlForMetar);
HttpURLConnection connection = null;
try {
xmlFile = null;
connection = (HttpURLConnection) url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
xmlFile = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
xmlFile.append(line).append("\n");
}
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
return xmlFile.toString();
}
@Override
public void unmarshalFileFromXmlToObject(String xmlFile) throws Exception {
JAXBContext jaxbContext = JAXBContext.newInstance(Data.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(xmlFile);
Data metarData = (Data) unmarshaller.unmarshal(reader);
System.out.println(metarData.getMetars().get(0).getStationId());
}
但我有这样的错误:
线程中的异常&#34; main&#34; javax.xml.bind.UnmarshalException:意外元素(uri:&#34;&#34;,local:&#34;响应&#34;)。预期元素是&lt; {} METAR&gt;,&lt; {} data&gt; at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext $ DefaultRootLoader.childElement(UnmarshallingContext.java:1131) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:374) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl $ NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:613) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl $ FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3132) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl $ PrologDriver.next(XMLDocumentScannerImpl.java:852) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505) 在com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841) 在com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770) 在com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) 在com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl $ JAXPSAXParser.parse(SAXParserImpl.java:643) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214) 在javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157) 在javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:214) 在com.przemyslawostrouch.parsers.XmlParser.unmarshalFileFromXmlToObject(XmlParser.java:59) 在com.przemyslawostrouch.main.WeatherAppApplication.main(WeatherAppApplication.java:24)
有什么问题?我读了一些关于对象工厂类的文章,它应该被创建吗? 第二个问题质量控制标志字段必须是数组而不是字符串?我想补充一点,我将来肯定不会使用这些数据。
<quality_control_flags>
<auto>TRUE</auto>
<auto_station>TRUE</auto_station>
<lightning_sensor_off>TRUE</lightning_sensor_off>
</quality_control_flags>