3

Is it possible to map existing xml schema to existing java classes?

I have several xml schemas and I need to map them all to one java class. Xml files differs a bit in way of storing data. E.g.

public class DataStorage {
   public String data1;
   public String data2;
   public String data3;
}

and set of different xml files

<?xml ...?>
<dataCase1>
<data1>...</data1>
<data2>...</data2>
<data3>...</data3>
</dataCase1>

<?xml ...?>
<dataCase2>
<data data1="..." data2="..." data3="..." />
</dataCase2>

<?xml ...?>
<dataCase3>
<data>
<innerData>
<data1>...</data1>
</innerData>
<otherData data2="...">
<data3>...</data3>
</otherData>
</data>
</dataCase3>

There could be many other variants of xml files.

Is it possible to bind all that files to java class using jaxb?

michael nesterenko
  • 14,222
  • 25
  • 114
  • 182

2 Answers2

2

You could use the EclipseLink MOXy implementation of JAXB to achieve this. As far as I understand, you will still have to create different classes for different types of schema but you can reuse your domain objects.

To continue with your example:

DataStorage class with 3 domain objects(data1, data2, data3), simplistically represented as Strings, can be really any JAXB mapped domain object.

  • Schema type 1

    @XmlRootElement(name = "dataCase")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class DataStorage {
        private String data1;
        private String data2;
        private String data3;
    
        /**
         * No-arg ctor needed by jaxb.
         */
        private DataStorage() {}
    
        public DataStorage(String data1, String data2, String data3) {
            this.data1 = data1;
            this.data2 = data2;
            this.data3 = data3;
        }
    
    }
    
  • Schema type 2. Note the use of the @XmlPath annotation.

     @XmlRootElement(name = "dataCase")
     @XmlAccessorType(XmlAccessType.FIELD)
     public class DataStorage {
         @XmlPath("data/@data1")
         private String data1;
         @XmlPath("data/@data2")
         private String data2;
         @XmlPath("data/@data3")
         private String data3;
     ....
    
  • Schema type 3. Again leveraging @XmlPath.

    @XmlRootElement(name = "dataCase")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class DataStorage {
        @XmlPath("data/innerData/data1/text()")
        private String data1;
        @XmlPath("data/otherData/@data2")
        private String data2;
        @XmlPath("data/otherData/data3/text()")
        private String data3;
    ....
    
  • Marshalling

    JAXBContext jc = JAXBContext.newInstance(DataStorage.class);
    Marshaller marshaller = jc.createMarshaller();
    DataStorage dataStorage = new DataStorage("data 1", "data 2", "data 3");
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    marshaller.marshal(dataStorage, System.out);
    

See this post from the MOXy team lead's blog for me information.

Sahil Muthoo
  • 12,033
  • 2
  • 29
  • 38
  • +1 - You can also use MOXy's XML metadata file to apply multiple mappings to your domain model. For an example see: http://stackoverflow.com/questions/6838882/jaxb-annotations-extract-xml-value-from-xml-element – bdoughan Sep 06 '11 at 14:09
  • @Blaise That looks great. This will come in handy some time :) – Sahil Muthoo Sep 06 '11 at 16:25
  • Here is a more detailed example I put together demonstrating multiple mappings on a single object model: http://blog.bdoughan.com/2011/09/mapping-objects-to-multiple-xml-schemas.html – bdoughan Sep 08 '11 at 19:25
1

You could use XSLT to translate your different XML formats into a single unified one.

Jules
  • 14,841
  • 9
  • 83
  • 130