gpt4 book ai didi

java - 如何使用 JAXB 生成唯一的元素名称或自动递增的元素名称?

转载 作者:数据小太阳 更新时间:2023-10-29 02:21:56 25 4
gpt4 key购买 nike

在使用 JAXB 编码为 XML 时,有没有办法自动增加集合的元素名称?我使用此代码生成 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>

我希望 groupsinstruments 自动递增,因此结果如下所示:

<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 模式,这行得通吗?

最佳答案

以下是处理此用例的几种方法:

选项 #1 - 使用标准 JAXB API

我在下面的回答扩展了 excellent answer given by Ilya .我已将其扩展为使用 XmlAdaptergetElements() 方法中删除逻辑。

Java 模型

默认设置

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 {

}

Xml 适配器

群组适配器

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);
}

}

仪器适配器

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>

选项 #2 - 使用 EclipseLink JAXB (MOXy) 的 @XmlVariableNode 扩展

下面是一个链接,指向如何使用我们在 EclipseLink JAXB (MOXy) 中添加的 hte @XmlVariableNode 扩展来映射此用例:

关于java - 如何使用 JAXB 生成唯一的元素名称或自动递增的元素名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23955462/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com