Java JAXB中如何处理多个@XmlID

Java JAXB中如何处理多个@XmlID,java,jaxb,Java,Jaxb,如果有一些@XmlID注释的属性具有相同的值,即使它们是不同的类型,JAXB也无法成功地解组对象,但是marshall很好 是虫子吗 或者,如何支持该功能 代码: 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.

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

是虫子吗

或者,如何支持该功能

代码:

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);
    }
}
包xml;
导入java.io.File;
导入java.io.FileNotFoundException;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入javax.xml.bind.JAXBContext;
导入javax.xml.bind.JAXBException;
导入javax.xml.bind.Marshaller;
导入javax.xml.bind.Unmarshaller;
导入javax.xml.bind.annotation.*;
导入javax.xml.bind.annotation.adapters.XmlAdapter;
导入javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
公共类多重ID{
静态公共类LongXmlAdapter扩展了XmlAdapter{
@凌驾
公共长解组(字符串s){
返回Long.parseLong(s);
}
@凌驾
公共字符串封送处理(长编号){
如果(number==null)返回“”;
返回编号.toString();
}
}
静态公共类元素{
私人长id;
@XmlID
@XmlAttribute(必需=true)
@XmlJavaTypeAdapter(LongXmlAdapter.class)
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
}
静态公共类组件{
私人长id;
@XmlID
@XmlAttribute(必需=true)
@XmlJavaTypeAdapter(LongXmlAdapter.class)
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
私人要素要素;
@XmlIDREF
@XmlAttribute(必需=true)
公共元素getElem(){
返回元素;
}
公共无效集合元素(元素e){
这个。elem=e;
}
}
@XmlRootElement
静态公共类容器{
private List elemLst=new ArrayList();
private List lst=new ArrayList();
@XmlElementWrapper(name=“elemList”)
@xmlement(name=“elem”)
公共列表getElemLst(){
return(elemLst!=null)?elemLst:(elemLst=newarraylist());
}
公共无效集合元素列表(列表元素列表){
this.elemLst=elemLst;
}
@XmlElementWrapper(name=“componentList”)
@xmlement(name=“component”)
公共列表getLst(){
返回(lst!=null)?lst:(lst=newarraylist());
}
公共无效集合lst(列表lst){
这是1.lst=lst;
}
}
静态公共类XmlSerialization{
公共静态对象读取(字符串文件路径、类…ClassEstoBeBind)引发FileNotFoundException{
对象实体=null;
试一试{
文件文件=新文件(文件路径);
如果(!file.exists())抛出新的FileNotFoundException(filepath);
JAXBContext context=JAXBContext.newInstance(classesToBeBound);
Unmarshaller um=context.createUnmarshaller();
实体=um.unmarshal(文件);
}捕获(JAXBEException-ex){
Logger.getLogger(xmlsialization.class.getName()).log(Level.SEVERE,null,ex);
}
返回实体;
}
公共静态无效写入(字符串文件路径、对象实体、类…ClasseStoBeBind){
文件文件=新文件(文件路径);
试一试{
JAXBContext context=JAXBContext.newInstance(classesToBeBound);
Marshaller m=context.createMarshaller();
m、 setProperty(Marshaller.JAXB_格式化的_输出,true);
m、 封送员(实体、文件);
}捕获(JAXBEException-ex){
Logger.getLogger(xmlsialization.class.getName()).log(Level.SEVERE,null,ex);
}
}
}
公共容器createContainer(){
容器=新容器();
对于(长i=1;i<5;++i){
元素elem=新元素();
元素setId(i);
container.getElemLst().add(elem);
组件组件=新组件();
公司设置ID(i);
公司设置要素(要素);
container.getLst().add(comp);
}
返回容器;
}
公共无效写入(字符串文件路径、容器){
write(filePath、container、container.class、Component.class、Element.class);
}
公共容器读取(字符串文件路径){
Container=null;
试一试{
container=(container)XmlSerialization.read(文件路径、container.class、Component.class、Element.class);
}捕获(FileNotFoundException ex){
Logger.getLogger(MultiID.class.getName()).log(Level.SEVERE,null,ex);
}
返回容器;
}
公共静态void main(字符串[]args){
多ID测试=新的多ID();
String filePath=“c:\\tmp.xml”;
容器c1=test.createContainer();
test.write(文件路径,c1);
容器c2=test.read(文件路径);
filePath=“c:\\tmp2.xml”;
test.write(文件路径,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,它将按预期工作

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

XML中的ID必须(a)在整个XML文档中唯一,(b)有效的XML名称(因此不能以数字开头)。而不是使用long,考虑字符串如<代码> E1 ,<代码> E2 < /代码>等元素和COD。