如何使用@XmlElement注释列表?

use*_*010 28 java xml annotations jaxb

我使用以下注释javax.xml.bind.annotation.XmlElement:

@XmlElement         
public List<String> getKeywords() {
    return keywords;
}
Run Code Online (Sandbox Code Playgroud)

当我编写一些示例内容时,会产生以下XML:

<keywords>keyword1</keywords>
<keywords>keyword2</keywords>
Run Code Online (Sandbox Code Playgroud)

我想获得以下XML:

<keywords>
    <keyword>keyword1</keyword>
    <keyword>keyword2</keyword>
</keywords>
Run Code Online (Sandbox Code Playgroud)

我应该使用什么样的注释?

我试过了

@XmlElementWrapper
@XmlElement(name="keyword")
Run Code Online (Sandbox Code Playgroud)

但随后整个内容消失,结果是:

<keywords/>
Run Code Online (Sandbox Code Playgroud)

如果我只尝试重命名元素,也会发生同样的情况:

@XmlElement(name="keyword")
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

更新:

这是根据第一个答案更新的类的完整代码,但它仍然无效(<keywords/>当编组为XML时,结果是一个空列表):

import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Content {

    private List<String> keywords;

    public Content() {}

    @XmlElementWrapper(name="keywords")
    @XmlElement(name="keyword")
    public List<String> getKeywords() {
        return keywords;
    }

    public void setKeywords(List<String> keywords) {
        this.keywords = keywords;
    }  

}
Run Code Online (Sandbox Code Playgroud)

我也尝试了以下相同的结果:

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.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Content {

    @XmlElementWrapper(name="keywords")
    @XmlElement(name="keyword")
    private List<String> keywords;

    public Content() {}

    public List<String> getKeywords() {
        return keywords;
    }

    public void setKeywords(List<String> keywords) {
        this.keywords = keywords;
    }  

}
Run Code Online (Sandbox Code Playgroud)

但是,关键字不为空,因为以下产生<keywords>keyword1</keywords><keywords>keyword2</keywords>而不是空列表:

import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Content {

    private List<String> keywords;

    public Content() {}

    @XmlElement
    public List<String> getKeywords() {
        return keywords;
    }

    public void setKeywords(List<String> keywords) {
        this.keywords = keywords;
    }  

}
Run Code Online (Sandbox Code Playgroud)

编组的代码是(JAX-RS):

import java.io.StringWriter;
import javax.ws.rs.Consumes;
import javax.ws.rs.Path;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

@Path("process")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_XML)
public class ContentHandler {

    @POST
    public Response process(Content content) {

        StringWriter stringWriter = new StringWriter();
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(Content.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.marshal(content, stringWriter);
        } catch (JAXBException e) {
            return Response.serverError().entity(e.getMessage()).build();
        }
        return Response.ok(stringWriter.toString(), MediaType.APPLICATION_XML).build();       
    }

}
Run Code Online (Sandbox Code Playgroud)

bdo*_*han 46

你需要利用@XmlElementWrapper@XmlElement.

Java模型

内容

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Content {

    private List<String> keywords;

    public Content() {}

    @XmlElementWrapper
    @XmlElement(name="keyword")
    public List<String> getKeywords() {
        return keywords;
    }

    public void setKeywords(List<String> keywords) {
        this.keywords = keywords;
    }  

}
Run Code Online (Sandbox Code Playgroud)

演示代码

演示

import java.util.*;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Content.class);

        List<String> strings = new ArrayList<String>(2);
        strings.add("foo");
        strings.add("bar");

        Content content = new Content();
        content.setKeywords(strings);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(content, System.out);
    }

}
Run Code Online (Sandbox Code Playgroud)

产量

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<content>
    <keywords>
        <keyword>foo</keyword>
        <keyword>bar</keyword>
    </keywords>
</content>
Run Code Online (Sandbox Code Playgroud)

欲获得更多信息

以下是我博客上几篇文章的链接,这些文章提供了更多信息:


Ada*_*old 17

使用此表格:

@XmlElementWrapper(name="keywords")
@XmlElement(name="keyword")
Run Code Online (Sandbox Code Playgroud)

请注意,如果keywords 是空的,那么你会得到<keywords />.

有时您需要添加@XmlRootElement到您的类(取决于上下文)和@XmlAccessorType(XmlAccessType.?)注释.我通常使用@XmlAccessorType(XmlAccessType.FIELD)和标注我的领域@XmlElement.