Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB Marshals root element without a close tag if it only has an attribute

Tags:

java

xml

jaxb

moxy

I am using JAXB / Moxy to marshal a class into XML. When the root element only contains an attribute the output is as follows:

    <?xml version="1.0" encoding="UTF-8"?>
    <procedure xmlns="http://xml.test.com/api/request" name="TestProcedure"/>

The desired output contains the closing tag for procedure:

   <?xml version="1.0" encoding="UTF-8"?>
   <procedure xmlns="http://xml.test.com/api/request" name="TestProcedure"></procedure>

This is getting sent to a third party system. Even though both are well formed XML, it still needs the closing tag.

I saw this post: JAXB marshals XML differently to OutputStream vs. StringWriter but did not see a difference in output between the outputstream and strings when running locally.

This seems to deal only with elements and attributes, but not the root element: Represent null value as empty element in xml jaxb I still setup a DescriptorCustomizer and looked through the ClassDescriptor in the debugger, but didn't see any properties to set like the XMLDirectMapping.

My domain object looks like

   @XmlRootElement(name = "procedure")
   public class ProcRequest {
    protected String procName;
    protected String requestId;
    protected List<Param> parameter;

    @XmlAttribute
    public String getProcName() {
        return procName;
    }
    public void setProcName(String procName) {
        this.procName = procName;
    }
    @XmlAttribute
    public String getRequestId() {
        return requestId;
    }
    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }
    @XmlElement
    public List<Param> getParam() {
        if (this.param == null) {
            this.param = new ArrayList<Param>();
        } 

        return param;
    }
    public void setParam(List<Param> param) {
        this.param = param;
    }

   }

And my service contains:

   ProcRequest procRequest = new ProcRequest();
   procRequest.setProcName("TestProcedure");

   JAXBContext jaxbContext = JAXBContext.newInstance(ProcRequest.class);

   Marshaller moxyMarshaller = jaxbContext.createMarshaller();
   moxyMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

   moxyMarshaller.marshal(procRequest, System.out);

Are there any properties or attributes which can be set to force a closing tag at the end similar to Marshaller.JAXB_FORMATTED_OUTPUT? Or any other suggestions?

like image 207
BenjaminDWest Avatar asked Oct 21 '22 02:10

BenjaminDWest


1 Answers

Since the two forms are semantically equivalent XML:

  1. the standard JAXB marshaler does not provide an option to control this detail; and
  2. any solution is going to have to be outside XML processing.

I believe you are stuck unless you can use a different JAXB or marshaler implementation that allows customization of empty tags. I think at one point Saxon had an option for this but haven't looked in years.

like image 142
Jim Garrison Avatar answered Oct 22 '22 15:10

Jim Garrison