gpt4 book ai didi

java - 如何在 JAXB 中处理多个@XmlID

转载 作者:行者123 更新时间:2023-11-30 09:32:02 31 4
gpt4 key购买 nike

如果有一些带有相同值的@XmlID 注释属性,即使它们属于不同类型,JAXB 也无法成功解码对象,但是编码很好。

这是一个错误吗?

否则,如何支持该功能?

代码:

package xml;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

public class MultiID {

static public class LongXmlAdapter extends XmlAdapter<String, Long> {
@Override
public Long unmarshal(String s) {
return Long.parseLong(s);
}

@Override
public String marshal(Long number) {
if (number == null) return "";

return number.toString();
}
}


static public class Element {
private Long id;

@XmlID
@XmlAttribute(required=true)
@XmlJavaTypeAdapter(LongXmlAdapter.class)
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}
}
static public class Component {
private Long id;

@XmlID
@XmlAttribute(required=true)
@XmlJavaTypeAdapter(LongXmlAdapter.class)
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

private Element elem;

@XmlIDREF
@XmlAttribute(required=true)
public Element getElem() {
return elem;
}

public void setElem(Element e) {
this.elem = e;
}
}
@XmlRootElement
static public class Container {
private List<Element> elemLst = new ArrayList<Element>();
private List<Component> lst = new ArrayList<Component>();

@XmlElementWrapper(name="elemList")
@XmlElement(name="elem")
public List<Element> getElemLst() {
return (elemLst != null)?elemLst:(elemLst = new ArrayList<Element>());
}

public void setElemLst(List<Element> elemLst) {
this.elemLst = elemLst;
}

@XmlElementWrapper(name="componentList")
@XmlElement(name="component")
public List<Component> getLst() {
return (lst != null)?lst:(lst = new ArrayList<Component>());
}

public void setLst(List<Component> lst) {
this.lst = lst;
}
}

static public class XmlSerialization {
public static Object read(String filepath, Class... classesToBeBound) throws FileNotFoundException {
Object entity = null;
try {
File file = new File(filepath);
if(!file.exists()) throw new FileNotFoundException(filepath);
JAXBContext context = JAXBContext.newInstance(classesToBeBound);
Unmarshaller um = context.createUnmarshaller();

entity = um.unmarshal(file);
} catch (JAXBException ex) {
Logger.getLogger(XmlSerialization.class.getName()).log(Level.SEVERE, null, ex);
}
return entity;
}

public static void write(String filePath, Object entity, Class... classesToBeBound) {
File file = new File(filePath);
try {
JAXBContext context = JAXBContext.newInstance(classesToBeBound);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(entity, file);
} catch (JAXBException ex) {
Logger.getLogger(XmlSerialization.class.getName()).log(Level.SEVERE, null, ex);
}
}

}
public Container createContainer() {
Container container = new Container();
for(long i = 1 ; i < 5; ++i) {
Element elem = new Element();
elem.setId(i);
container.getElemLst().add(elem);
Component comp = new Component();
comp.setId(i);
comp.setElem(elem);
container.getLst().add(comp);
}
return container;
}
public void write(String filePath, Container container) {
XmlSerialization.write(filePath, container, Container.class, Component.class, Element.class);
}
public Container read(String filePath) {
Container container = null;
try {
container = (Container)XmlSerialization.read(filePath, Container.class, Component.class, Element.class);
} catch (FileNotFoundException ex) {
Logger.getLogger(MultiID.class.getName()).log(Level.SEVERE, null, ex);
}
return container;
}

public static void main(String[] args) {
MultiID test = new MultiID();
String filePath = "c:\\tmp.xml";
Container c1 = test.createContainer();
test.write(filePath, c1);
Container c2 = test.read(filePath);
filePath = "c:\\tmp2.xml";
test.write(filePath, c2);
}
}

输出:

[tmp.xml]

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<container>
<elemList>
<elem id="1"/>
<elem id="2"/>
<elem id="3"/>
<elem id="4"/>
</elemList>
<componentList>
<component id="1" elem="1"/>
<component id="2" elem="2"/>
<component id="3" elem="3"/>
<component id="4" elem="4"/>
</componentList>
</container>

[tmp2.xml]

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<container>
<elemList>
<elem id="1"/>
<elem id="2"/>
<elem id="3"/>
<elem id="4"/>
</elemList>
<componentList>
<component id="1"/>
<component id="2"/>
<component id="3"/>
<component id="4"/>
</componentList>
</container>

tmp2.xml 中的每个“组件”都没有元素引用。那就是问题所在。例如,如果我们从 100 开始更改组件 ID,它将按预期工作。

如何解决这个问题?非常感谢。

最佳答案

您的输出是由于 JAXB (JSR-222) 的实现中存在错误所致你正在使用。使用 JDK 1.7.0 for the Mac 和 EclipseLink JAXB (MOXy) 中包含的 JAXB impl 运行示例代码我得到了 tmp2.xml 的预期结果。

tmp2.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<container>
<elemList>
<elem id="1"/>
<elem id="2"/>
<elem id="3"/>
<elem id="4"/>
</elemList>
<componentList>
<component elem="1" id="1"/>
<component elem="2" id="2"/>
<component elem="3" id="3"/>
<component elem="4" id="4"/>
</componentList>
</container>

关于java - 如何在 JAXB 中处理多个@XmlID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12651521/

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