0

I would like to use JAXB for mapping XML file to object. How to convert XML file like this:

<Contract>
    <Variable Name="Address">
        <Value>Address</Value>
    </Variable>
    <Variable Name="FirstName">
        <Value>First</Value>
    </Variable>
    <Variable Name="SecondName">
        <Value>Second</Value>
    </Variable>
    <Parameter Name="id">
        <Value>399425</Value>
    </Parameter>
    <Parameter Name="isComplete">
        <Value>True</Value>
    </Parameter>
    <Parameter Name="templateName">
        <Value>Probate Application</Value>
    </Parameter>
</Contract>

To java object like this:

public class Contract {
    private Long id;
    private String templateName;
    private boolean isComplete;
    private Map<String, String> answers = new HashMap<>();

}

Or maybe advice some tutorial for this. Thank you

5
  • This seems to be relevant. Commented Jul 1, 2016 at 12:24
  • @Sviatlana If you are using IntelliJ IDEA you can look at Generating Java Code from XML Schema post. Commented Jul 1, 2016 at 12:28
  • It is not supported in Community.. Commented Jul 1, 2016 at 12:48
  • So, if i understand your problem, your want all your Parameter elements to be represented as Typed objects and all your Variable elements to be stored in a map with the name attribute as key and the value as the text in Value elements ? Commented Jul 1, 2016 at 13:54
  • @Dimpre Jean-Sébastien exactly! Commented Jul 1, 2016 at 14:03

1 Answer 1

1

You have two problems : Binding the <Variable> Element to your Map and Binding the <Parameter> elements to different typed Objects.

I'll treat the problems in this order.

For the Map, you'll have to use a XmlAdapter with @XmlJavaTypeAdapter.

Code a class representing your <Variable> element and map it :

public class Variable{

    @XmlAttribute
    public String Name;

    @XmlElement
    public String Value;

    //Getters and setters
}

Then code the XmlAdapter :

public class YourAdapter extends XmlAdapter<List<Variable>,Map<String,String>>{

    public Map<String,String> unmarshall(List<Variable> arg0){
         //Logic to convert a List<Variable> into a Map<String,String> and return it
    }

    public List<Variable> marshall(Map<String,String> arg0){
         //Logic to convert a Map<String,String> into a List<Variable> and return it
    }


}

Then map your Contract class :

@XmlRootElement
@XmlSeeAlso({Variable.class})
public class Contract{

     @XmlElement(name="Variable")
     @XmlJavaTypeAdapter(YourAdapter.class)
     private Map<String,String> map;

     //Getters and setters
}

With this, your map should work.

You have two solutions with your second problem : Either Using JAXB Reference implementation or Using JAXB MOXy implementation.

With JAXB reference implementation

JAXB Reference implementation cannot use Xpath to do its binding. So here is a workaround.

Code a second class and adapter for your <Parameter> element, which is basically going to be the same thing except for the names, and use this mapping for contract :

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Variable.class,Parameter.class})
public class Contract{

     @XmlElement(name="Variable")
     @XmlJavaTypeAdapter(YourAdapter.class)
     private Map<String,String> map;

     @XmlElement(name="Parameter")
     @XmlJavaTypeAdapter(YourAdapterForParameter.class)
     private Map<String,String> parameterMap;

     public Long getId(){
          return Long.valueOf(parameterMap.get("id"));
     }

     public void setId(Long id){
          parameterMap.put("id",id.toString());
     }

     //Same thing for other getters/setters
}

With MOXy implementation

With MOXy implementation, you can use @XmlPath and XPath to make it a bit cleaner :

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Variable.class})
public class Contract{

     @XmlPath("./Variable[@Name='id']/Value")
     private Long id;

     @XmlPath("./Variable[@Name='templateName']/Value")
     private String templateName;

     @XmlPath("./Variable[@Name='isComplete']/Value")
     private boolean isComplete;

     @XmlElement(name="Variable")
     @XmlJavaTypeAdapter(YourAdapter.class)
     private Map<String,String> map;

     //Getters and setters
}

For further information/help, please refer to JAXB/MOXy Documentation.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.