java JAXB XML 解析的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16003005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 21:36:17  来源:igfitidea点击:

Problems with JAXB XML parsing

javaxmllistxml-parsingjaxb

提问by David

I'm working on a project in which I will use JAXB to parse an XML file containing the following weather station information: Name, station ID, latitude/longitude, and url. Right now I intend to test everything by printing a weather station by name only. I have debugged my code but when I try to run: I get the following error:

我正在处理一个项目,在该项目中我将使用 JAXB 解析包含以下气象站信息的 XML 文件:名称、站 ID、纬度/经度和 url。现在我打算通过仅按名称打印气象站来测试所有内容。我已经调试了我的代码,但是当我尝试运行时:我收到以下错误:

Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"wx_station_index"). Expected elements are (none)

线程“main”javax.xml.bind.UnmarshalException 中的异常:意外元素(uri:“”,本地:“wx_station_index”)。预期元素为(无)

Does anyone have an explanation? Any help would be appreciated. My code and sample of XML are posted below:

有人有解释吗?任何帮助,将不胜感激。我的代码和 XML 示例发布如下:

//create criteria for weather station info
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class StationTest {

/**
 * @param args
 */

@XmlElement(name = "station_id")
String station_id;

@XmlElement(name = "state")
String state;

@XmlElement(name = "station_name")
String stationName;

@XmlElement(name = "latitude")
double latitude;

@XmlElement(name = "longitude")
double longitude;

@XmlElement(name = "html_url")
String htmlUrl;

public String getStationID(){
    return station_id;
}

public void setStationId(String station_id)
{
     this.station_id = station_id;
}

public String getState(){
    return state;
}

public void setState(String state)
{
     this.state = state;
}

public String getStationName(){
    return stationName;
}

public void setStationName(String station_name)
{
     this.stationName = stationName;
}

public double getLatitude(){
    return latitude;
}

public void setLatitude(double latitude)
{
     this.latitude = latitude;
}

public double getLongitude(){
    return longitude;
}

public void setLongitude(double longitude)
{
     this.longitude = longitude;
}

public String getUrl(){
    return htmlUrl;
}

public void setUrl(String url){
    this.htmlUrl = htmlUrl;

}

} import java.util.ArrayList;

导入 java.util.ArrayList;

import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlAccessType;

//create list for all weather stations

@XmlRootElement
@XmlSeeAlso(value = StationTest.class)
@XmlAccessorType(XmlAccessType.FIELD)
public class StationListTest {

/**
 * @param args
 */
@XmlElement(name = "station")
private ArrayList<StationTest> stationList;

public void setStationListTest(ArrayList<StationTest> StationList){
    this.stationList = StationList;
}

public ArrayList<StationTest> getStationListTest(){
    return stationList;
}

}

import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;

 import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

//final Test of JAXB
public class Test3 {

/**
 * @param args
 */
//read xml
private static final String STATION_XML = "src/flwxindex3.xml";

//main method
public static void main(String[] args) throws InterruptedException, JAXBException, FileNotFoundException {

    //create list object
    ArrayList<StationTest> StationList = new ArrayList<StationTest>();

    final JAXBContext jaxbc = JAXBContext.newInstance(StationListTest.class);
    final Unmarshaller unmarshaller = jaxbc.createUnmarshaller();

    //create list for iteration, then iterate printing by name only
    StationListTest stationListTest = (StationListTest) unmarshaller.unmarshal(new FileReader(STATION_XML));
    ArrayList<StationTest> list = stationListTest.getStationListTest();
    //final StationListTest stations = (StationListTest) unmarshaller.unmarshal(Thread.currentThread().getContextClassLoader().getResource("src/flwxindex3.xml"));
    for (final StationTest station : list) {
        System.out.println(station.getStationName());
    }
}

}

}

The actual xml as requested (Thought I included it, sorry):

请求的实际 xml(以为我包含了它,抱歉):

<?xml version="1.0" encoding="UTF-8"?>
<wx_station_index>
    <credit>NOAA's National Weather Service</credit>
    <credit_URL>http://weather.gov/</credit_URL>
    <image>
            <url>http://weather.gov/images/xml_logo.gif</url>
            <title>NOAA's National Weather Service</title>
            <link>http://weather.gov</link>
    </image>
    <suggested_pickup>08:00 EST</suggested_pickup>
    <suggested_pickup_period>1140</suggested_pickup_period>

<station>
    <station_id>NFNA</station_id>
    <state>FJ</state>
    <station_name>Nausori</station_name>
    <latitude>-18.05</latitude>
    <longitude>178.567</longitude>
    <html_url>http://weather.noaa.gov/weather/current/NFNA.html</html_url>
    <rss_url>http://weather.gov/xml/current_obs/NFNA.rss</rss_url>
    <xml_url>http://weather.gov/xml/current_obs/NFNA.xml</xml_url>
</station>

<station>
    <station_id>KCEW</station_id>
    <state>FL</state>
            <station_name>Crestview, Sikes Airport</station_name>
    <latitude>30.79</latitude>
    <longitude>-86.52</longitude>
            <html_url>http://weather.noaa.gov/weather/current/KCEW.html</html_url>
            <rss_url>http://weather.gov/xml/current_obs/KCEW.rss</rss_url>
            <xml_url>http://weather.gov/xml/current_obs/KCEW.xml</xml_url>
</station>

回答by 3xil3

Assuming that wx_station_index is not a typo.

假设 wx_station_index 不是错字。

I've added some annotations to instruct jaxb on what part of the xml to map on what part of your code. Changing your StationListTest to the following should work a whole lot better.

我添加了一些注释来指示 jaxb 将 xml 的哪一部分映射到代码的哪一部分。将您的 StationListTest 更改为以下内容应该会更好。

import java.util.ArrayList;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

//create list for all weather stations
@XmlRootElement(name="wx_station_index")
public class StationListTest {

/**
 * @param args
 */
@XmlElement(name="station")    
private ArrayList<StationTest> StationList;

public StationListTest(){
    StationList=new ArrayList<StationTest>();
}

public void setStationListTest(ArrayList<StationTest> StationList){
    this.StationList = StationList;
}

public ArrayList<StationTest> getStationListTest(){
    return StationList;
}

}

回答by Perception

There is a mismatch between the named property StationListon your class StationListTestand the implicit stationlist attribute in the XML document. This needs to be resolved by explicitly defining what elements of your XML the StationListproperty be populated from:

StationList类上的命名属性与 XML 文档中StationListTest的隐式station列表属性不匹配。这需要通过显式定义StationList属性填充的XML 元素来解决:

@XmlElement(name = "station")
private ArrayList<StationTest> StationList;

Some other quick notes:

其他一些快速说明:

  • You should follow Java naming patterns (camel case) for class and variable names. So StationListshould be stationList, for example).
  • As a general rule you should annotate all your top level data classes with @XMLRootElement.
  • As a general rule, you should use the most generic form of a type when defining your Java class (List, instead of ArrayList).
  • You should indicate which other classes are involved in your mapping with an @XmlSeeAlso
  • 对于类名和变量名,您应该遵循 Java 命名模式(驼峰式大小写)。例如,StationList应该是这样stationList)。
  • 作为一般规则,您应该使用@XMLRootElement.
  • 作为一般规则,您应该在定义 Java 类时使用最通用的类​​型形式(List, 而不是ArrayList)。
  • 您应该使用 @XmlSeeAlso

The following class definitions work with your XML:

以下类定义适用于您的 XML:

@XmlRootElement(name = "station")
@XmlAccessorType(XmlAccessType.FIELD)
public class StationTest {

    @XmlElement(name = "station_id")
    String stationId;

    String state;

    @XmlElement(name = "station_name")
    String stationName;

    double latitude;
    double longitude;

    @XmlElement(name = "html_url")
    String htmlUrl;

    // Constructor, getters, setters
}

@XmlRootElement(name = "wx_station_index")
@XmlSeeAlso(value = StationTest.class)
@XmlAccessorType(XmlAccessType.FIELD)
public class StationListTest {
    @XmlElement(name = "station")
    private List<StationTest> stationList;

    // Constructors, getters, setters
}