是的,如果您使用委托 getter 和 setter,您可以将 na、nb、nc 和 nd 值存储在嵌套对象中。
我总是发现更容易确保类和 @Xml... 注释是好的,首先从 Java 编组 XML,然后通过解组返回并打印结果来验证解析。
在下面的代码中,我稍微压缩了几行,以便您一次可以看到更多内容。你可能不会在你的真实代码中这样做。
我也依赖默认命名,所以我不必在注释上给出任何值。
这里是功能齐全的代码,可准确生成您显示的 XML,并将其解析回来。
class MotorProperties {
private String na;
private String nb;
private String nc;
private String nd;
public MotorProperties() {
}
public MotorProperties(String na, String nb, String nc, String nd) {
this.na = na;
this.nb = nb;
this.nc = nc;
this.nd = nd;
}
public void setNa(String na) { this.na = na; }
public void setNb(String nb) { this.nb = nb; }
public void setNc(String nc) { this.nc = nc; }
public void setNd(String nd) { this.nd = nd; }
public String getNa() { return this.na; }
public String getNb() { return this.nb; }
public String getNc() { return this.nc; }
public String getNd() { return this.nd; }
@Override
public String toString() {
return "MotorProperties[na=" + this.na +
", nb=" + this.nb +
", nc=" + this.nc +
", nd=" + this.nd + "]";
}
}
请注意,上面的MotorProperties 类没有任何@Xml... 注释,因为JAXB 不会直接使用它。
@XmlAccessorType(XmlAccessType.NONE)
class Motor {
@XmlAttribute private long id;
@XmlAttribute private String type;
@XmlAttribute private String model;
private MotorProperties props;
public Motor() {
this.props = new MotorProperties();
}
public Motor(long id, String type, String model, String na, String nb, String nc, String nd) {
this.id = id;
this.type = type;
this.model = model;
this.props = new MotorProperties(na, nb, nc, nd);
}
public void setNa(String na) { this.props.setNa(na); }
public void setNb(String nb) { this.props.setNb(nb); }
public void setNc(String nc) { this.props.setNc(nc); }
public void setNd(String nd) { this.props.setNd(nd); }
@XmlElement public String getNa() { return this.props.getNa(); }
@XmlElement public String getNb() { return this.props.getNb(); }
@XmlElement public String getNc() { return this.props.getNc(); }
@XmlElement public String getNd() { return this.props.getNd(); }
@Override
public String toString() {
return "Motor[id=" + this.id +
", type=" + this.type +
", model=" + this.model +
", props=" + this.props + "]";
}
}
使用上面的XmlAccessType.NONE,仅处理@Xml... 注释的字段/方法。这允许更好的控制。使用委托将MotorProperties 类的所有值作为直接属性提供。
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
class Car {
@XmlElement private int nWheels;
@XmlElement private int nDoors;
@XmlElement private List<Motor> motor;
public Car() {
}
public Car(int nWheels, int nDoors, Motor... motor) {
this.nWheels = nWheels;
this.nDoors = nDoors;
this.motor = Arrays.asList(motor);
}
public List<Motor> getMotor() {
return this.motor;
}
@Override
public String toString() {
return "Car[nWheels=" + this.nWheels +
", nDoors=" + this.nDoors + "]";
}
}
测试
Car car = new Car(4, 5,
new Motor(1, "cc", "kly", "A", "B", "C", "D"),
new Motor(2, "cc2", "kly2", "E", "F", "G", "H"));
JAXBContext jaxbContext = JAXBContext.newInstance(Car.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter xmlWriter = new StringWriter();
marshaller.marshal(car, xmlWriter);
String xml = xmlWriter.toString();
System.out.println(xml);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Car car2 = (Car) unmarshaller.unmarshal(new StringReader(xml));
System.out.println(car2);
car2.getMotor().forEach(m -> System.out.println(" " + m));
输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<car>
<nWheels>4</nWheels>
<nDoors>5</nDoors>
<motor id="1" type="cc" model="kly">
<na>A</na>
<nb>B</nb>
<nc>C</nc>
<nd>D</nd>
</motor>
<motor id="2" type="cc2" model="kly2">
<na>E</na>
<nb>F</nb>
<nc>G</nc>
<nd>H</nd>
</motor>
</car>
Car[nWheels=4, nDoors=5]
Motor[id=1, type=cc, model=kly, props=MotorProperties[na=A, nb=B, nc=C, nd=D]]
Motor[id=2, type=cc2, model=kly2, props=MotorProperties[na=E, nb=F, nc=G, nd=H]]