У меня есть список модулей в древовидной структуре.Базовый класс содержит дочерние и некоторые общие свойства, в то время как производный класс должен предоставлять свои отдельные поля.Теперь, когда я пытаюсь сериализовать это с JAXB, я получаю только членов базового класса, но не членов производных классов.
Application.java
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Application
{
public static void main(String[] args)
{
try
{
Emulators emulators = new Emulators();
emulators.addChild(new VICEModule());
emulators.addChild(new VICEModule());
StringWriter sw = new StringWriter();
JAXBContext jaxbContext = JAXBContext.newInstance(emulators.getClass());
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // Pretty print
jaxbMarshaller.marshal(emulators, sw);
String s = sw.toString();
System.out.println(s);
}
catch(Throwable e)
{
System.err.println("Exception:"+e);
}
}
}
ModuleBase.java
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import com.sun.xml.internal.txw2.annotation.XmlAttribute;
public class ModuleBase
{
private List<ModuleBase> mChilds = new ArrayList<>();
private String mModuleId;
private String mModuleName;
public ModuleBase(String oModuleId, String oModuleName)
{
setModuleId(oModuleId);
setModuleName(oModuleName);
}
public void addChild(ModuleBase oModuleNode)
{
mChilds.add(oModuleNode);
}
@XmlElement(name="ModuleList")
public List<ModuleBase> getChildModules()
{
return mChilds;
}
@XmlAttribute
public String getModuleId()
{
return mModuleId;
}
public void setModuleId(String oModuleId)
{
mModuleId = oModuleId;
}
@XmlAttribute
public String getModuleName()
{
return mModuleName;
}
public void setModuleName(String oModuleName)
{
mModuleName = oModuleName;
}
}
Emulators.java
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Emulators")
public class Emulators
extends ModuleBase
{
public Emulators()
{
super("IdEmu129872q53", "Emulators");
}
}
VICEModule.java
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;
@XmlRootElement(name = "VICEModule")
public class VICEModule
extends ModuleBase
{
private String mInstallationPath;
private int mPort;
public VICEModule()
{
super("Id123456", "Vice");
mPort = 6510;
}
//@XmlElement(name="InstallationPath")
@XmlValue
public String getInstallationPath()
{
return mInstallationPath;
}
public void setInstallationPath(String oPath)
{
mInstallationPath = oPath;
}
//@XmlElement(name="Port")
@XmlValue
public int getPort()
{
return mPort;
}
public void setPort(int nPort)
{
mPort = nPort;
}
}
Теперь, когда я сериализую его, я получаю следующий XML, где отсутствуют значения VICEModule, а такжемодуль указан как ModuleList
вместо VICEModule
, а базовые поля помещены в виде тегов вместо атрибутов:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Emulators>
<ModuleList>
<moduleId>Id123456</moduleId>
<moduleName>Vice</moduleName>
</ModuleList>
<ModuleList>
<moduleId>Id123456</moduleId>
<moduleName>Vice</moduleName>
</ModuleList>
<moduleId>IdEmu129872q53</moduleId>
<moduleName>Emulators</moduleName>
</Emulators>
Итак, как это должно выглядеть:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Emulators ModuleId="IdEmu129872q53" ModuleName="Emulators">
<VICEModule ModuleId="Id1" ModuleName="Name">
<InstallationPath>Path1</InstallationPath>
<Port>6510</Port>
</VICEModule>
<VICEModule ModuleId="Id2" ModuleName="Name">
<InstallationPath>Path2</InstallationPath>
<Port>6511</Port>
</VICEModule>
</Emulators>
Когда я использую VICEModule
в качестве базового класса, тогда XML выглядит более похожим на него (но без атрибутов).