Let's say I only need a few attributes of 'child'
<parent>
<child name="Child" age="1" />
</parent>
I dont want to have to create a 'child' class. I just want to wrap it and fetch the attribute. Is this possible? Is there any wrapper annotation I can use?
CodePudding user response:
Well, you can do it but if you don't take the traditional method then it will become really tricky. Here is the code which you can try:
XML:
<parent>
<child name="Child" age="1" />
</parent>
Root:
@XmlRootElement(name = "parent")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Root {
@XmlJavaTypeAdapter(Adapter.class)
private String child;
}
Child:
@Data
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Child {
@XmlAttribute
private String name;
@XmlAttribute
private String age;
}
Adapter:
public class Adapter extends XmlAdapter<Child, String> {
public String unmarshal(Child pC) throws Exception {
System.out.println(pC.toString());
return null;
}
public Child marshal(String pC) throws Exception {
return null;
}
}
Main:
public class Main {
public static void main(String[] args) throws JAXBException, XMLStreamException {
final InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("sample.xml");
final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(Root.class).createUnmarshaller();
final Root root = unmarshaller.unmarshal(xmlStreamReader, Root.class).getValue();
System.out.println(root.toString());
}
}
Output:
Child(name=Child, age=1)
Updated to store everything without child classes
XML:
<parent>
<child name="Child" age="1" />
</parent>
Root:
@Data
@XmlRootElement(name = "parent")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlAnyElement
private List<Object> any;
}
Main:
public class Main {
public static void main(String[] args) throws JAXBException, XMLStreamException {
final InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("sample.xml");
final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(Root.class).createUnmarshaller();
final Root root = unmarshaller.unmarshal(xmlStreamReader, Root.class).getValue();
System.out.println(root.toString());
Marshaller marshaller = JAXBContext.newInstance(Root.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "US-ASCII");
//marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", new XmlCharacterHandler());
marshaller.marshal(root, System.out);
}
}
XML:
Root(any=[[child: null]])
<?xml version="1.0" encoding="US-ASCII"?>
<parent>
<child age="1" name="Child"/>
</parent>