我有XML结构。

<cars>
    <car name = "BMW" engine="2.5"/>
    <car name = "Lexus" engine="4.5"/>
    <car name = "VW" engine="1.4"/>
    <car name = "Honda" engine="2.0"/>
</cars>


我有每种汽车模型的Java类。

public class BMW extends Car{

    public BMW(){


    }


}


如何设计main()类来解析此XML,并原子调用所需Car的构造函数。假设我得到一个节点,这意味着我想调用BMW构造函数创建一个BMW对象并将所有内容存储到List 中。

感谢您的提示! :)

最佳答案

您可以利用XmlAdapter使用任何JAXB (JSR-222)映射此用例:

车载适配器

在您的示例中,您使用自定义节点作为继承指示器。使用标准的JAXB API,我们可以使用XmlAdapter映射此用例。 XmlAdapter从域对象转换为易于JAXB实现(Metro,MOXy,JaxMe等)映射的对象。

package forum9812778;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class CarAdapter extends XmlAdapter<CarAdapter.AdaptedCar, Car> {

    @Override
    public AdaptedCar marshal(Car car) throws Exception {
        AdaptedCar adaptedCar = new AdaptedCar();
        adaptedCar.name = car.getClass().getSimpleName();
        adaptedCar.engine = car.getEngine();
        return adaptedCar;
    }

    @Override
    public Car unmarshal(AdaptedCar adaptedCar) throws Exception {
        Car car;
        if("BMW".equals(adaptedCar.name)) {
            car = new BMW();
        } else if("Lexus".equals(adaptedCar.name)) {
            car = new Lexus();
        } else if("VW".equals(adaptedCar.name)) {
            car = new VW();
        } else if("Honda".equals(adaptedCar.name)) {
            car = new Honda();
        } else {
            return null;
        }
        car.setEngine(adaptedCar.engine);
        return car;
    }

    public static class AdaptedCar {
        @XmlAttribute
        public String name;

        @XmlAttribute
        public String engine;
    }

}


汽车

@XmlJavaTypeAdapter批注用于将XmlAdapterCar类关联:

package forum9812778;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
@XmlJavaTypeAdapter(CarAdapter.class)
public class Car {

    private String engine;

    public String getEngine() {
        return engine;
    }

    public void setEngine(String engine) {
        this.engine = engine;
    }

}


宝马

下面是其中一个子类的示例。

package forum9812778;

public class BMW extends Car {

}


汽车

我们需要一个Object表示树中的根节点。我们将定义Cars类以充当此角色:

package forum9812778;

import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Cars {

    private List<Car> car;

    public List<Car> getCar() {
        return car;
    }

    public void setCar(List<Car> car) {
        this.car = car;
    }

}


演示版

package forum9812778;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Cars.class);

        File xml = new File("src/forum9812778/input.xml");
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Cars cars = (Cars) unmarshaller.unmarshal(xml);

        for(Car car : cars.getCar()) {
            System.out.println(car.getClass());
        }

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(cars, System.out);
    }

}


输出量

class forum9812778.BMW
class forum9812778.Lexus
class forum9812778.VW
class forum9812778.Honda
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cars>
    <car engine="2.5" name="BMW"/>
    <car engine="4.5" name="Lexus"/>
    <car engine="1.4" name="VW"/>
    <car engine="2.0" name="Honda"/>
</cars>


了解更多信息


http://blog.bdoughan.com/2012/01/jaxb-and-inhertiance-using-xmladapter.html

10-02 04:56