I've been fiddling around with JAXB for a while now, I need to generate xml like below
<Root attr1="" attr2="" .. attrn="" >
<CNode attr1="" attr2="" />
.
.
.
<CNode .. />
</Root>
The attributes of Root element is dynamic and would come from either a properties file or a template. What is the best way to get it into the structure as shown above? I'm using hashmaps for dynamic variables and then tried mapping it with XmlJavaTypeAdapter, the best I could do is
<Root>
<Attribs>
<entry key="attr1">Value</entry>
</Attribs>
<CNode .. />
</Root>
Is there a way in jaxb to say use hashmap's key as the attribute name and the value for that key as the value for that attribute in xml? Or if you think there is a better way to do it, I'm open for suggestions. I'm quite thinking about using jaxb's marshaller to add the Root node separately. However it would be nicer if I can just use jaxb's adapter. Thanks!
@XmlAnyAttribute is along the lines of what you need:
Root
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.namespace.QName;
@XmlRootElement(name="Root")
public class Root {
private Map<QName, String> extension;
private List<CNode> cnodes;
@XmlAnyAttribute
public Map<QName, String> getExtension() {
return extension;
}
public void setExtension(Map<QName, String> extension) {
this.extension = extension;
}
@XmlElement(name="CNode")
public List<CNode> getCnodes() {
return cnodes;
}
public void setCnodes(List<CNode> cnodes) {
this.cnodes = cnodes;
}
}
CNode
import java.util.Map;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.namespace.QName;
public class CNode {
private Map<QName, String> extension;
@XmlAnyAttribute
public Map<QName, String> getExtension() {
return extension;
}
public void setExtension(Map<QName, String> extension) {
this.extension = extension;
}
}
Demo
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Root root = (Root) unmarshaller.unmarshal(new File("input.xml"));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
input.xml
<?xml version="1.0" encoding="UTF-8"?>
<Root att1="A" att2="B">
<CNode att3="C" att4="D"/>
<CNode att5="E" att6="F"/>
</Root>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With