Home > other >  JAXB XML; How to fetch an attribute of an element without needing to create a pojo of the element?
JAXB XML; How to fetch an attribute of an element without needing to create a pojo of the element?

Time:09-17

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>
  • Related