5
votes

I'm trying to unmarshal an xml file using JAXB. When I am using @XmlElement with the correct name and namespace the unmarshalling works (e.g. @XmlElement(name = "name", namespace="http://www.test.com"))

If I use XmlType together with propOrder it unfortunately does not anymore (e.g. @XmlType(namespace="http://www.test.com", name = "", propOrder = {"name", "description"})).

The content of the xml file (test.xml):

<Operation xmlns="http://www.test.com">
  <Parameter>
    <name>Param1</name>
    <description>Description of Parameter1</description>
  </Parameter>
  <Parameter>
    <name>Param2</name>
    <description>Description of Parameter2</description>
  </Parameter>
</Operation>

The content of JAXBExample.java is:

package stackoverflow.problem.jaxb.ns;

import java.io.FileNotFoundException;
import java.io.FileReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

public class JAXBExample {

  public static void main(String[] args) throws JAXBException, FileNotFoundException   {
  String xmlFilename = "test.xml";

    JAXBContext context = JAXBContext.newInstance(Operation.class);

    System.out.println("Output from our XML File: ");
    Unmarshaller um = context.createUnmarshaller();
    Operation op = (Operation) um.unmarshal(new FileReader(xmlFilename));

    System.out.println("Operation-Content: " + op);
  }

}

The content of

package stackoverflow.problem.jaxb.ns;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;


@XmlRootElement(name="Operation", namespace="http://www.test.com")
@XmlAccessorType(XmlAccessType.FIELD)

public class Operation {

  @XmlElement(name = "Parameter", namespace="http://www.test.com")
  List<Parameter> parameterList;

  @Override
  public String toString(){
    String retVal = "";
    for(Parameter currentParameter: parameterList){
      retVal += currentParameter.toString() + "\n";
    }   
    return retVal;
  }
}

And the Content of Parameter.java is:

package stackoverflow.problem.jaxb.ns;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlType(namespace="http://www.test.com", name = "", propOrder = {"name", "description"})
@XmlAccessorType(XmlAccessType.FIELD)
public class Parameter {

  //@XmlElement(name = "name", namespace="http://www.test.com")
  String name;

  //@XmlElement(name = "description", namespace="http://www.test.com")
  String description;

  @Override
  public String toString(){
    return this.name + "\t" + this.description;
  }
}

If I uncomment the two @XmlElement lines in the last code block (Parameter.java), the unmarshalling works fine. If those two lines are not included, both fields in the Parameter object are null. Is there another way to declare a namespace when using propOrder in XmlType? Or did I do something else wrong?

1

1 Answers

6
votes

The namespace can also be defined per package, in a file named package-info.java, this way you don't have to repeat it on every class or field:

@javax.xml.bind.annotation.XmlSchema (
    namespace = "http://www.test.com",
    elementFormDefault=javax.xml.bind.annotation.XmlNsForm.QUALIFIED
)
package stackoverflow.problem.jaxb.ns;