如何在JAXB中为动态元素添加动态属性

时间:2017-12-01 06:14:21

标签: java jaxb

尝试动态创建任何具有属性的元素 现在能够创建没有属性的动态元素, 需要帮助为动态创建的元素添加属性。

动态元素创建

  public class CustomElement {


        private  List<JAXBElement<String>> Elements;


        @XmlAnyElement
        public List<JAXBElement<String>> getElements() {
            return Elements;
        }

        public void setElements(List<JAXBElement<String>> elements) {
            Elements = elements;
        }


        public void setElements(Map<String, String>  myElements, String namespaceURI) {

               List<JAXBElement<String>> elements = new ArrayList<JAXBElement<String>>();
                for (Map.Entry<String, String> mapElement: myElements.entrySet()) 
                {               
                    JAXBElement jAXBElement=new JAXBElement(new QName(namespaceURI,mapElement.getKey()), 
                            String.class, mapElement.getValue());

                    elements.add(jAXBElement);
                }
            Elements = elements;
        }

//not working attr added to parent element not to current element
     private Map<QName, String> attr;

        @XmlAnyAttribute
        public Map<QName, String> getAttr() {
            return attr;
        }

        public void setAttr(Map<QName, String> attr) {
            this.attr = attr;
        }

    }

设定值

 Map<String, String> myElements =new HashMap<String,String>();  

             myElements.put("connectmrf ","");  
                setElements(myElements,"www.xxxxx.xxx/xxx/vmas");

             Map<QName, String> attr=new HashMap<QName,String>();   
                attr.put(new QName("Name"),"Amit");  
                attr.put(new QName("age"),"10");  

                setAttr(attr);

当前结果:

     <state  age="10" Name="Amit">
            <vmas:connectmrf ></vmas:connectmrf >
      </state>

预期结果:请建议

     <state>
            <vmas:connectmrf  age="10" Name="Amit" ></vmas:connectmrf >
      </state>

1 个答案:

答案 0 :(得分:3)

警告!:这只是一种快速而又肮脏的编组方式

您需要使用@XmlAnyAttribute创建包装类 例如:

public class AnyXmlElement {
    @XmlAnyAttribute
    private Map<QName, String> attributes;
    @XmlAnyElement
    private List<Object> elements;

    public AnyXmlElement() {
        attributes = new LinkedHashMap<QName, String>();
        elements = new ArrayList<Object>();
    }

    public void addAttribute(QName name, String value) {
        attributes.put(name, value);
    }

    public void addElement(Object element) {
        elements.add(element);
    }
}

通过将AnyXmlElement包裹在JAXBElement

中来确保动态名称
public static JAXBElement<AnyXmlElement> toJAXBElement(QName qName, AnyXmlElement any) {
    return new JAXBElement<AnyXmlElement>(qName, AnyXmlElement.class, any);
}

为了测试,我们创建了一个简单的根类

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public static class Root {
    @XmlAnyElement
    public List<Object> any;
}

和程序

public static void main(String[] args) throws Exception {
    AnyXmlElement any = new AnyXmlElement();
    any.addAttribute(new QName("bar"), "hello");

    Root root = new Root();
    root.any = Arrays.asList(toJAXBElement(new QName("foo"), any));
    // It's important to add AnyXmlElement.class here
    JAXBContext jc = JAXBContext.newInstance(Root.class, AnyXmlElement.class);
    Marshaller m = jc.createMarshaller();
    m.marshal(root, System.out);
}

这是生成的xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><root><foo bar="hello world"/></root>