有没有办法在使用JAXB编组到XML时自动增加Collection的元素名称?我使用以下代码生成XML:
public void saveTestSettings(final String filename, final DefaultTestSettings t) throws Exception
{
try
{
final Path path = FileSystems.getDefault().getPath((paths.getTestSettingsPath() + filename));
if (Files.notExists(path.getParent()))
throw new Exception(path.getParent().toString() + " does not exist!!");
final OutputStream out = new BufferedOutputStream(Files.newOutputStream(path));
final JAXBContext jaxbContext = JAXBContext.newInstance(DefaultTestSettings.class);
final Marshaller m = jaxbContext.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(t, out);
out.flush();
out.close();
}
catch (JAXBException | IOException e)
{
e.printStackTrace();
throw new Exception(e.getMessage());
}
}
生成的XML如下所示:
<defaultTestSettings>
<groups>
<instruments>
<name>A200</name>
</instruments>
<name>A0</name>
</groups>
<groups>
<instruments>
<name>A300</name>
</instruments>
<instruments>
<name>A400</name>
</instruments>
<name>A1</name>
</groups>
</defaultTestSettings>
我希望groups
和instruments
自动递增,以便结果如下所示:
<defaultTestSettings>
<groups1>
<instruments1>
<name>A200</name>
</instruments1>
<name>A0</name>
</groups1>
<groups2>
<instruments1>
<name>A300</name>
</instruments1>
<instruments2>
<name>A400</name>
</instruments2>
<name>A1</name>
</groups2>
</defaultTestSettings>
我对使用XML架构不太熟悉,那会起作用吗?
答案 0 :(得分:3)
您可以使用@XmlAnyElement注释进行此操作
简单示例groups
标记。
@XmlRootElement(name = "defaultTestSettings")
@XmlSeeAlso(Group.class)
public class DefaultTestSettings
{
private static int counter = 1;
private static final String PROP = "group";
List<Group> groups = new ArrayList<Group>();
@XmlAnyElement
public List<JAXBElement<Group>> getElements()
{
final List<JAXBElement<Group>> retVal = new ArrayList<>();
for (final Group g : groups)
{
retVal.add(new JAXBElement(new QName(PROP + counter++), Group.class, g));
}
return retVal;
}
}
答案 1 :(得分:3)
以下几种方式可以处理这个用例:
我在下面的回答扩展了excellent answer given by Ilya。我已将其扩展为使用XmlAdapter
从getElements()
方法中删除逻辑。
<强> DefaultSettings 强>
import java.util.*;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class DefaultSettings {
private List<Groups> groups = new ArrayList<Groups>();
@XmlAnyElement
@XmlJavaTypeAdapter(GroupsAdapter.class)
public List<Groups> getGroups() {
return groups;
}
}
<强>组强>
import java.util.*;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
public class Groups {
private List<Instruments> instruments = new ArrayList<Instruments>();
@XmlAnyElement
@XmlJavaTypeAdapter(InstrumentsAdapter.class)
public List<Instruments> getInstruments() {
return instruments;
}
}
<强>仪器强>
public class Instruments {
}
<强> GroupsAdapter 强>
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.namespace.QName;
public class GroupsAdapter extends XmlAdapter<JAXBElement<Groups>, Groups> {
private int counter = 1;
private InstrumentsAdapter instrumentsAdapter = new InstrumentsAdapter();
public InstrumentsAdapter getInstrumentsAdapter() {
return instrumentsAdapter;
}
@Override
public Groups unmarshal(JAXBElement<Groups> v) throws Exception {
return v.getValue();
}
@Override
public JAXBElement<Groups> marshal(Groups v) throws Exception {
instrumentsAdapter.resetCounter();
return new JAXBElement<Groups>(new QName("groups" + counter++), Groups.class, v);
}
}
<强> InstrumentsAdapter 强>
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.namespace.QName;
public class InstrumentsAdapter extends XmlAdapter<JAXBElement<Instruments>, Instruments> {
private int counter = 1;
@Override
public Instruments unmarshal(JAXBElement<Instruments> v) throws Exception {
return v.getValue();
}
@Override
public JAXBElement<Instruments> marshal(Instruments v) throws Exception {
return new JAXBElement<Instruments>(new QName("instruments" + counter++), Instruments.class, v);
}
public void resetCounter() {
counter = 1;
}
}
<强>演示强>
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(DefaultSettings.class, Groups.class, Instruments.class);
Groups groups1 = new Groups();
groups1.getInstruments().add(new Instruments());
groups1.getInstruments().add(new Instruments());
Groups groups2 = new Groups();
groups2.getInstruments().add(new Instruments());
groups2.getInstruments().add(new Instruments());
DefaultSettings ds = new DefaultSettings();
ds.getGroups().add(groups1);
ds.getGroups().add(groups2);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
GroupsAdapter groupsAdapter = new GroupsAdapter();
marshaller.setAdapter(groupsAdapter);
marshaller.setAdapter(groupsAdapter.getInstrumentsAdapter());
marshaller.marshal(ds, System.out);
}
}
<强>输出强>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<defaultSettings>
<groups1>
<instruments1/>
<instruments2/>
</groups1>
<groups2>
<instruments1/>
<instruments2/>
</groups2>
</defaultSettings>
@XmlVariableNode
扩展下面是如何使用我们在EclipseLink JAXB(MOXy)中添加的hte @XmlVariableNode
扩展来映射此用例的链接: