有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用@XmlElement注释列表?

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

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

当我整理一些示例内容时,它会生成以下XML:

<keywords>keyword1</keywords>
<keywords>keyword2</keywords>

我希望获得以下XML:

<keywords>
    <keyword>keyword1</keyword>
    <keyword>keyword2</keyword>
</keywords>

我应该使用哪种注释

我试过了

@XmlElementWrapper
@XmlElement(name="keyword")

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

<keywords/>

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

@XmlElement(name="keyword")

我做错了什么

更新:

下面是根据第一个答案更新的类的完整代码,但它仍然不起作用(当封送到XML时,结果是一个空列表<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() {}

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

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

}

我还尝试了以下方法,得到了相同的结果:

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;
    }  

}

但是,关键字不是空的,因为下面生成的是<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;
    }  

}

编组的代码是(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();       
    }

}

共 (3) 个答案

  1. # 1 楼答案

    使用此表格:

    @XmlElementWrapper(name="keywords")
    @XmlElement(name="keyword")
    

    请注意,如果keywords为空,则您将得到<keywords />

    有时需要将@XmlRootElement添加到类中(取决于上下文)和@XmlAccessorType(XmlAccessType.?)注释。我通常使用@XmlAccessorType(XmlAccessType.FIELD)并用@XmlElement注释我的字段

  2. # 2 楼答案

    上面布莱斯·道格汉的回答是完全正确的

    另一种简单的方法是,即使您不编写-@xmlementwrapper

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

    您可以这样使用它-在类级别编写XmlAccessorType,那么XML元素名称将与类成员名称-关键字相同

    import java.util.List;
    import javax.xml.bind.annotation.*;
    
    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Content {
    
        private List<String> keywords;
    
        public Content() {}
    
    
        public List<String> getKeywords() {
            return keywords;
        }
    
        public void setKeywords(List<String> keywords) {
            this.keywords = keywords;
        }  
    
    }
    
  3. # 3 楼答案

    您需要利用@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;
        }  
    
    }
    

    演示代码

    演示

    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);
        }
    
    }
    

    输出

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <content>
        <keywords>
            <keyword>foo</keyword>
            <keyword>bar</keyword>
        </keywords>
    </content>
    

    更多信息

    以下是我的博客中提供附加信息的几篇文章的链接: