当前位置: 首页 > 面试题库 >

使用JAXB编组/解组Java超类和子类

解鸿运
2023-03-14
问题内容

我一直在尝试JAXB教程,并设法使代码能够从Java对象生成XML文件,然后能够使用XML生成Java对象。目前,它读取同一类的多个实例以创建一个类似于以下内容的XML文件

<Car>
    <regplate>TR54</regplate>
    <colour>red</colour>
    <energyrating>5</energyrating>
</Car>
<Car>
    <regplate>BN04 THY</regplate>
    <colour>yellow</colour>
    <energyrating>3</energyrating>
</Car>
<Car>
    <regplate>BN05 THY</regplate>
    <colour>yellow</colour>
    <energyrating>5</energyrating>
</Car>

我希望能够使用JAXB技术来处理子类。例如:说我有一个Car,Van和Bicycle对象,它们是Vehicle的子类。我是否可以操纵我的JAXB类来编写一个会产生类似结果的XML文件?我在下面提供了我正在使用的代码。

<Vehicle>
    <Car>
        <regplate>TR54</regplate>
        <colour>red</colour>
        <energyrating>5</energyrating>
    </Car>
    <Van>
        <regplate>MN05 RFD</regplate>
        <colour>red</colour>
        <energyrating>5</energyrating>
    </Van>
    <Car>
        <regplate>ZX54 UJK</regplate>
        <colour>red</colour>
        <energyrating>1</energyrating>
    </Car>
</Vehicle>

主班

package basictransport2;

public class Main
{
    public static void main(String[] args)
    {
        JAXB parser = new JAXB();
        parser.marshall();
        //parser.unmarshallList();
    }
}

车辆类别

package basictransport2;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

//@XmlRootElement(name = "Vehicle")
public class Vehicle
{
    private int ownerId;

    public Vehicle(int ownerId)
    {
        this.setOwnerId(ownerId);
    }

    //@XmlElement (name = "Owner ID")
    public int getOwnerId()
    {
        return ownerId;
    }

    public void setOwnerId(int ownerId)
    {
        this.ownerId = ownerId;
    }


    public int getEnergyRating()
    {
        return (Integer) null;
    }


    public String getColour()
    {
        return null;
    }

    public String getRegPlate()
    {
        return null;
    }
}

车类

package basictransport2;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

//@XmlRootElement(name = "Car")
public class Car extends Vehicle
{
    private String regPlate;
    private int energyRating;
    private String colour;

    public Car(String regPlate, int energyRating, String colour, int ownerId)
    {
        super(ownerId);
        this.regPlate = regPlate;
        this.energyRating = energyRating;
        this.colour = colour;
    }

    public Car(int ownerId)
    {
        super(ownerId);
    }

    //@XmlElement (name = "Registration")
    public String getRegPlate()
    {
        return regPlate;
    }

    public void setRegPlate(String regPlate)
    {
        if(this.regPlate == null)
        {
            this.regPlate = regPlate;
        }
    }

    //@XmlElement (name = "Energy Rating")
    public int getEnergyRating()
    {
        return energyRating;
    }

    public void setEnergyRating(int energyRating)
    {
        this.energyRating = energyRating;
    }

    //@XmlElement (name = "Colour")
    public String getColour()
    {
        return colour;
    }

    public void setColour(String colour)
    {
        this.colour = colour;
    }
}

JAXB类

package basictransport2;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

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

public class JAXB
{   
    public void marshall()
    {
        try
        {
            List<Vehicle> vehicleList = new ArrayList<Vehicle>();

            vehicleList.add(new Car("SG09 TYH", 4, "Yellow", 1));
            vehicleList.add(new Car("XX09 VVV", 3, "Red", 2));
            vehicleList.add(new Car("BL09 TYZ", 4, "Blue", 3));

            Garage listOfVehicles = new Garage();
            listOfVehicles.setListOfVehicles(vehicleList);

            JAXBContext context = JAXBContext.newInstance(Garage.class);
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(listOfVehicles, System.out);
            marshaller.marshal(listOfVehicles, new File("src\\data\\listcar.xml"));
        }

        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
    }

    public void unmarshall()
    {
        try
        {
            JAXBContext context = JAXBContext.newInstance(Garage.class);
            Unmarshaller unmarhsaller = context.createUnmarshaller();
            Garage listOfVehicles = (Garage)unmarhsaller.unmarshal(new File("src\\data\\listcar.xml"));
            System.out.println("List Car information");

            for(Vehicle vehicle : listOfVehicles.getListOfVehicles())
            {
                System.out.println("Reg Plate: " + vehicle.getRegPlate());
                System.out.println("Energy Rating: " + vehicle.getEnergyRating());
                System.out.println("Colour: " + vehicle.getColour());
                System.out.println("================");
            }    
        }

        catch (Exception e)
        {
            System.out.println(e.getMessage());
        }
    }
}

清单类别

package basictransport2;

import java.util.ArrayList;
import java.util.List;

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

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="Vehicle")
public class Garage
{
    @XmlElements
    ({
        @XmlElement(name = "Car", type = Car.class, required = false)
    })

    private List<Vehicle> vehicleCollection = new ArrayList<Vehicle>();

    public List<Vehicle> getListOfVehicles()
    {
        return vehicleCollection;
    }

    public void setListOfVehicles(List<Vehicle> listOfVehicles)
    {
        this.vehicleCollection = listOfVehicles;
    }
}

问题答案:

谢谢各位的意见。我使用了所有答案的反馈,但最终都是有效的结合了这就是为什么我为将来可能遇到此问题的任何人创建单独的答案。

为了使它起作用,我必须确保在marhsalled /
unmarshalled的super和sub类中的所有getter方法都用标注@XmlElement。这将确定相应变量的XML标签。

@XmlElement (name = "OwnerID")
    public int getOwnerId()
    {
        return ownerId;
    }

必须对超类进行注释,@XmlSeeAlso以将子类绑定到它。即在我的代码中RoadVehicle是超类,并且CarVan类都对其进行了扩展。

@XmlSeeAlso({Car.class, Van.class})
public class Vehicle
{

现在使用超级类和子类进行注释,唯一需要注释的其他类是列表类(在我的代码中为车库)。此处的更改将确定填充了哪些XML标签。

通过将@XmlRootElement注释应用于类的顶部来设置XML根标签。即“车辆”将是我的示例中的根XML标签。

@XmlRootElement(name = "Vehicle")
public class Garage
{

最后,@XmlElements必须@XmlElements为每个需要XML标签的子类声明一个带有注释的列表,并name提供XML标签的名称。必须在该集合的getter方法上方声明此列表。

@XmlElements
    ({
        @XmlElement(name = "Car", type = Car.class, required = false),
        @XmlElement(name = "Van", type = Van.class, required = false)
    })    
    public List<Vehicle> getListOfVehicles()
    {
        return vehicleCollection;
    }


 类似资料:
  • 问题内容: 我正在尝试创建一个非常简单的REST服务器。我只是有一个测试方法,它将返回字符串列表。这是代码: 它给出以下错误: 我希望JAXB对诸如String,Integer等简单类型具有默认设置。我想不是。这是我的想象: 使这种方法最简单的方法是什么? 问题答案: 我使用@LiorH的示例并将其扩展为: 注意,它使用泛型,因此您可以将其与String之外的其他类一起使用。现在,应用程序代码很简

  • 问题内容: 我遵循此经常引用的博客文章中有关使用xsi:type的说明: http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using- xsitype.html 基本上我有这个: 而这个测试: 我得到这个结果: 我已经尝试了JAXB的默认实现jaxb- impl-2.1.2,并基于此bug尝试了jaxb- impl-2.2.6-b38.j

  • 下面是这篇经常被引用的博客文章中关于使用xsi:type的说明: http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-xsitype.html 基本上我有这个: 这个测试: 我得到了这个结果: 我尝试了JAXB的默认实现,JAXB-impl-2.1.2,并基于此缺陷,尝试了JAXB-impl-2.2.6-b38。罐子这些都不管用。

  • 问题内容: 我正在构建一系列链接的类,我希望它们的实例能够编组到XML,以便可以将它们保存到文件中并在以后再次读取。 目前,我正在使用以下代码作为测试用例: XML输出为: 元素为空是否有原因?我希望它包含日期(即)的字符串表示形式。为此,我是否需要编写自己的代码? 输出为: 问题答案: 您将必须创建一个这样的: 并使用 另请参阅是否要在程序包级别定义适配器。

  • 问题内容: 我正在使用JAXB读写XML。我想要的是使用基本JAXB类进行编组,并使用继承的JAXB类进行编组。这是允许发送方Java应用程序将XML发送到另一个接收方Java应用程序。发送者和接收者将共享一个公共的JAXB库。我希望接收者将XML解组为接收者特定的JAXB类,该类扩展了通用JAXB类。 例: 这是发送方使用的常见JAXB类。 这是在解组XML时使用的特定于接收者的JAXB类。接收

  • 我正在尝试使用JAXB从遗留系统中解压XML文档。我的xml结构如下所示: