13

I use JAXB to create XML messages. The XML I need to create is (for the sake of simplicity):

<request>
  <header/>
</request>

My code looks like this:

import javax.xml.bind.annotation.*;

@XmlRootElement(name = "request")
public class Request {

    private String header;

    @XmlElement(required=true)
    public String getHeader() {
      return header;
    }

    public void setHeader(String header) {
      this.header=header;
    }
}

The problem: the header element is not displayed (header is null). When header is set to an empty string, the following is displayed:

<request>
  <header></header>
</request>

When I use as type Object instead of String, the result is even worse:

<request>
  <header xsi:type="xs:string" 
   xmlns:xs="http://www.w3.org/2001/XMLSchema" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></header>
</request>

BTW: I'm using this code to create the XML string.

Is it possible to get an empty tag?

Community
  • 1
  • 1
doekman
  • 18,750
  • 20
  • 65
  • 86
  • So what is wrong with setting header to ""? – Tom Hawtin - tackline Feb 27 '09 at 12:28
  • I want
    and not
    .
    – doekman Feb 27 '09 at 12:51
  • @doekman Ehm, I know it's late, but just in case. To do EXACTLY what you want, you can use [EclipseLink MOXy](http://www.eclipse.org/eclipselink/moxy.php) implementation of JAXB, which has a very nice extension `@XmlNullPolicy`. See an example [here](http://stackoverflow.com/a/11748678/814702) (in the "Option #2" section) – informatik01 Aug 28 '13 at 21:38

4 Answers4

12

In XML, <header/> and <header></header> are the same thing. If you really want the former, then use a prettifier. javax.xml.transform.TransformerFactory.newTransformer() will probably do that for you.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
5

An empty tag for a String object is essentially the empty string.

If you call the following, you will get what you are looking for:

request.setHeader("")

I should also note that in XML the following two declarations of a header are idential. Both of these have no child text nodes. These are essentially the same and will be treated the same by all XML parsers:

<header></header>

<header/>
Chris Dail
  • 25,715
  • 9
  • 65
  • 74
  • 1
    Hi Chris, what if one wants to create an empty tag for wrapper objects like Boolean, BigInteger, BigDecimal, etc? Apparently setting null to those will result in the tags not being generated. – Min Naing Oo Aug 25 '20 at 14:05
2

As @Tom Hawtin - tackline said

<header/> and <header></header> is same. Parsers will give you "".

You have to to put nillable on your header annotation

@XmlElement(nillable=true, required=true)
public String getHeader() {
  return header;
}

I hope this code will generate following XML for null value.

import javax.xml.bind.*;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Request {

    public static void main(String[] args) throws JAXBException {
        final Request request = new Request();
        final JAXBContext context = JAXBContext.newInstance(Request.class);
        final Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
                               Boolean.TRUE);
        marshaller.marshal(request, System.out);
        System.out.flush();
    }

    @XmlElement(nillable=true, required=true)
    private String header;
}

prints

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<request>
    <header xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</request>
informatik01
  • 16,038
  • 10
  • 74
  • 104
Jin Kwon
  • 20,295
  • 14
  • 115
  • 184
0

I wanted the same thing, effectively <header/> rather than <header></header> during the xml serialization process.

Since a null value - rather than an empty string - will produce the correct result, I modified my setter method to set the value explicitly to null:

public void setHeader(String header) {
    this.header = "".equals(header) ? null : header;
}
Mark D
  • 919
  • 8
  • 6