Search code examples
javaxmljakarta-eexml-parsingxml-binding

Issue regarding Java to XML conversion and vice versa


I have XML like this which I get from middleware

<Example library="somewhere">

   <book>

     <AUTHORS_TEST>Author_Name</AUTHORS_TEST>
     <EXAMPLE_TEST>Author_Name</EXAMPLE_TEST>

   </book>

</Example>

What I want to do is convert the XML to Java object(and Vice Versa) as:

class Example
 {

 private String authorsTest;
 private String exampleTest;

  }

So Is there any way to map these two,The thing to be noted is that XML Tag Name and the Class attribute name is different,So can anyone suggest to implement this with minimal changes?Xstream is a good Choice,but if I have large number of fields it will be difficult to add aliases,so any better choices other than XStream?


Solution

  • Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.

    Most XML-binding libraries require an object per level of nesting in the XML representation. EclipseLink JAXB (MOXy) has the @XmlPath extension that enables XPath based mapping to remove this restriction.

    Example

    Below is a demonstration of how the @XmlPath extension can be applied to your use case.

    package forum10511601;
    
    import javax.xml.bind.annotation.*;
    import org.eclipse.persistence.oxm.annotations.XmlPath;
    
    @XmlRootElement(name="Example")
    @XmlAccessorType(XmlAccessType.FIELD)
    class Example {
    
        @XmlAttribute
        private String library;
    
        @XmlPath("book/AUTHORS_TEST/text()")
        private String authorsTest;
    
        @XmlPath("book/EXAMPLE_TEST/text()")
        private String exampleTest;
    
    }
    

    jaxb.properties

    To specify MOXy as your JAXB provider you need to add a file named jaxb.properties in the same package as your domain model with the following entry (see Specifying EclipseLink MOXy as Your JAXB Provider).

    javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
    

    Demo

    As MOXy is a JAXB (JSR-222) implementation, you use the standard JAXB runtime APIs (which are included in the JRE/JDK starting with Java SE 6).

    package forum10511601;
    
    import java.io.File;
    import javax.xml.bind.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(Example.class);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            File xml = new File("src/forum10511601/input.xml");
            Example example = (Example) unmarshaller.unmarshal(xml);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(example, System.out);
        }
    
    }
    

    input.xml/Output

    <?xml version="1.0" encoding="UTF-8"?>
    <Example library="somewhere">
       <book>
          <AUTHORS_TEST>Author_Name</AUTHORS_TEST>
          <EXAMPLE_TEST>Author_Name</EXAMPLE_TEST>
       </book>
    </Example>