I wonder if someone can help me with a JAXB problem.
If I have an abstract class with 2 concrete implementations: For example (I have left out most of the markup/xml for brevity):
Map
Is there a way to have the xml below unmarshall correctly to the appropriate concrete class
Do
rather than the following:
abstract class Credential
{
public abstract CredentialDLL Map();
}
class SNMP : Credential
{
public override CredentialDLL Map()
{
return new SNMPMapper().Map(this);
}
}
class HTTP : Credential
{
public override CredentialDLL Map()
{
return new HTTPMapper().Map(this);
}
}
// Simplified do method, it is now a one liner
CredentialDLL Do(Credential input)
{
return input.Map();
}
The reason I need this is to be backward compatible with our already published API.
Thanks in advance.
答案 0 :(得分:2)
我刚才在俄语社区回答了类似的问题。可能你正在寻找类似的东西:
df = speed_df.merge(temp_df, how='outer', on='ts')
df = df.rename(columns=dict(val_x='speed', val_y='temp'))
df = df.sort_values('ts')
df.fillna(method='ffill')
一些简单的例子:
@XmlElements({
@XmlElement(name = "car", type = Car.class),
@XmlElement(name = "van", type = Van.class)
})
public List<Vehicle> getVehicles() {
return vehicles;
}
输出将是:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.*;
import java.io.StringReader;
import java.util.List;
public class Test {
public static void main(String... args) throws JAXBException {
String xmldata = "<request><car></car><van></van></request>";
StringReader reader = new StringReader(xmldata);
JAXBContext jaxbContext = JAXBContext.newInstance(Request.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Request request = (Request) unmarshaller.unmarshal(reader);
for (Vehicle object : request.getVehicles()) {
System.out.println(object.getClass());
}
}
}
@XmlRootElement(name = "request")
class Request {
private List<Vehicle> vehicles;
@XmlElements({
@XmlElement(name = "car", type = Car.class),
@XmlElement(name = "van", type = Van.class)
})
public List<Vehicle> getVehicles() {
return vehicles;
}
public void setVehicles(List<Vehicle> vehicles) {
this.vehicles = vehicles;
}
}
abstract class Vehicle {
}
class Van extends Vehicle {
}
class Car extends Vehicle {
}
<强> UPD 强>:
评论后更新。对于单个条目,无论如何都可以删除class Car
class Van
:
List
希望这会有所帮助。
答案 1 :(得分:1)
You can use annotations and annotate the concrete implementations. In this case @XmlType() above Car or Van. This way you will keep your xml generic.