如何使用JAXB创建Java对象

5

我正在尝试从xml文件创建Java对象。 我正在使用jaxb(解组)创建Java对象。 我遇到了错误javax.xml.bind.UnmarshalException:unexpected element(uri:“http://www.w3.org/2001/XMLSchema”,local:“schema”)。 预期的元素是

我查了一下谷歌,发现我们需要xsd文件才能做到这一点...所以我使用apache inst2xsd工具将其转换为xsd。 我正在使用以下Java代码:

import java.io.FileNotFoundException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.UnmarshalException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="report")
public class Report 
{
    public static void main(String [] args) throws FileNotFoundException
    {
        try
        {
            JAXBContext jc = JAXBContext.newInstance(new Class[] {com.bcbsks.testjb.Report.class});             
            Unmarshaller um = jc.createUnmarshaller();          
            Report myJAXBObject = (Report)um.unmarshal(new java.io.FileInputStream("report.xsd"));
        } 
        catch( UnmarshalException ue ) 
        {    
            ue.printStackTrace(); 
        } 
        catch( JAXBException je ) 
        { 
            je.printStackTrace(); 
        } 
    }
}

但我遇到了以下错误:
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"schema"). Expected elements are  (none)

请问我做错了什么?

非常感谢您的帮助。

2个回答

6
我认为您缺少了一些步骤。您没有发布 report.xsd 是什么,也没有提供样本 xml,因此我会猜测一下。
首先,您正在尝试取消编组 xsd 而不是 xml,这本身就是问题的根源。话虽如此,您的 Report.java 类看起来没有正确生成,因此即使您尝试针对 xml 文件进行取消编组,它也不太可能起作用。
如果您有一个正确创建的 XSD 文件,第一件事情应该是使用 xjc 创建 JaxB POJOs。xjc 已安装在 java 中,您可以使用它从 xsd 创建带注释的 java 类。它还将创建 2 个附加文件 - ObjectFactory.java 和 package-info.java,这些文件由 JAXB 使用。 (您可以使用 -d 参数指定输出路径(请参阅 --help 以获取完整的开关列表))
xjc -d c:\dev\myproject\src\main\java report.xsd

一旦您生成了这些文件,您需要基于该包/文件创建JAXBContext。

JAXBContext jc = JAXBContext.newInstance(something.generated.Report.class);             
Unmarshaller um = jc.createUnmarshaller();          
Report myJAXBObject = (Report)um.unmarshal(new java.io.FileInputStream("report.xsd"), Report.class).getValue();

Unmarshaller 会生成一个 JAXBElement,你可以从中提取实际的报告类。希望这能帮到你。

unmarchal(FileInputStream, Class<T>) 没有方法签名。 - thomas.mc.work
很抱歉 @thomas.mc.work,我已不再参与这个项目或使用Jaxb了,但我怀疑这个方法在过去三年中可能已经被废弃或删除了。你可以尝试查看较旧版本的Jaxb,看看这个方法是否被标记为已废弃/被其他方法替代了。不幸的是,我无法记得这是哪个版本的jaxb。 - Eric B.
我已经找到了一种替代方法,使用ObjectMapper,它也是由xjc创建的:https://dev59.com/Qonca4cB1Zd3GeqP5AZn#31405556 - thomas.mc.work

4

您尝试取消编组的Bean上没有任何属性。但更重要的是,您正在尝试从XSD本身反序列化对象。错误消息在这里是一个很好的指示器:

unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"schema")

JAXB会输出此错误消息,因为它试图将XSD的元数据映射到Bean的属性上。当然,您的Bean实际上没有任何属性。错误消息的下一部分也表明了这一点:

Expected elements are (none)

您需要正确定义Java Bean(添加一些属性!),并获取表示序列化版本的XML文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接