How to instantiate an empty element with JAXB

2019-01-18 13:19发布

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?

标签: java xml jaxb
4条回答
ゆ 、 Hurt°
2楼-- · 2019-01-18 13:37

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.

查看更多
劫难
3楼-- · 2019-01-18 13:47

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>
查看更多
贼婆χ
4楼-- · 2019-01-18 14:02

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;
}
查看更多
Deceive 欺骗
5楼-- · 2019-01-18 14:03

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/>
查看更多
登录 后发表回答