没有实际编写一个编写器并将每个元素附加到字符串上。有没有办法让JAXB marshaller编组一个对象列表,我可以给它一个顶级元素的名称?
我觉得我很接近这个
//http://blog.bdoughan.com/2012/07/jaxb-no-annotations-required.html
public <T> String jaxb(Collection<T> o, Class<T> clazz, String plural){
try {
ArrayList<T> al = new ArrayList<T>(o.size());
al.addAll(o);
JAXBContext jc = JAXBContext.newInstance(ArrayList.class);
JAXBElement<ArrayList> amenity = new JAXBElement(new QName(plural), ArrayList.class, al);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter writer = new StringWriter();
marshaller.marshal(amenity, writer);
return writer.toString();
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
但结果仍然以空列表的形式返回
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<pluralName/>
有没有办法在不手动粘贴xml字符串的情况下执行此操作?
在Michael Glavassevich的帮助下,我已经能够做到这一点,但有一个警告,个别元素是<Item>
s
//http://blog.bdoughan.com/2012/07/jaxb-no-annotations-required.html
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> String jaxb(Collection<T> elements, Class<T> elementClass, String plural){
try {
T[] array = (T[]) Array.newInstance(elementClass, elements.size());
elements.toArray(array);
JAXBContext jc = JAXBContext.newInstance(array.getClass());
JAXBElement<T[]> topElement = new JAXBElement(new QName(plural), array.getClass(), array);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter writer = new StringWriter();
marshaller.marshal(topElement, writer);
return writer.toString();
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
结果变为
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Basketballs>
<item>basketball one</item>
<item>basketball two</item>
</Basketballs>
答案 0 :(得分:4)
如果您不想创建包装类,可以将该集合转换为数组,将该数组放在JAXBElement
中,然后封送它。
例如:
public class JAXBArrayWriter {
public static class Item {
@XmlValue
protected String value;
public Item() {}
public Item(String value) {
this.value = value;
}
}
public static void main (String [] args) throws Exception {
List<Item> items = new ArrayList<Item>();
items.add(new Item("one"));
items.add(new Item("two"));
JAXBContext jc = JAXBContext.newInstance(Item[].class);
JAXBElement<Item[]> root = new JAXBElement<Item[]>(new QName("items"),
Item[].class, items.toArray(new Item[items.size()]));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter writer = new StringWriter();
marshaller.marshal(root, writer);
System.out.println(writer.toString());
}
}
产生以下文件:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<items>
<item>one</item>
<item>two</item>
</items>
答案 1 :(得分:2)
请试试这个:
首先,创建一个列表类:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class AmenityList {
@XmlElement(name = "amenity")
List<Amenity> amenities = new ArrayList<Amenity>();
public AmenityList() {}
public void setList(List<Amenity> amenities) {
this.amenities = amenities;
}
}
然后是Amenity类:
@XmlAccessorType(XmlAccessType.FIELD)
class Amenity {
private String amenityName;
private String amenityDate;
public Amenity(String name, String date) {
this.amenityName = name;
this.amenityDate = date;
}
}
在列表中设置您需要的设施 - 可能是一种不那么冗余的方式:) - 并将其分配给AmenityList:
AmenityList amenityList = new AmenityList();
List <Amenity> amenities = new ArrayList<Amenity>();
amenities.add(new Amenity("a_one", "today"));
amenities.add(new Amenity("a_two", "tomorrow"));
amenity.setList(amenities);
最后是一个toXml方法:
public static String toXml(AmenityList amenityList) throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(AmenityList.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(amenityList, sw);
return sw.toString()
}
获得,即:
<amenityList>
<amenity>
<amenityName>a_one</amenityName>
<amenityDate>today</amenityDate>
</amenity>
<amenity>
<amenityName>a_two</amenityName>
<amenityDate>tomorrow</amenityDate>
</amenity>
</amenityList>
答案 2 :(得分:0)
尝试一下。
POJO类:
.about-image {
/*position: relative;
display: inline-block; /* Make the width of box same as image */
float: right;
z-index:1;
margin-top: 75px;
margin-bottom: 75px;
margin-right: 30px;
}
.about-image .overlay {
font-family: "Raleway", "";
/*
position: absolute;
*/
bottom: 0px;
left: 0px;
background: rgba(0, 0, 0, 0.8);
font-family: Arial,sans-serif;
color: #fff;
width: 100%; /* Set the width of the positioned div */
height: 5%;
}
.overlay a {
text-decoration: none;
color: #fff;
font-family: "Raleway", "";
text-align: left;
}
.overlay a:hover {
color: #941313;
transition: linear .4s;
}
.further h1 {
color: black;
font-family: "Raleway", "";
font-weight: bold;
font-size: 40px;
padding-top: 75px;
padding-right: 10px;
padding-left: 70px;
}
.further h2 {
color: black;
font-family: "Raleway", "";
font-weight: bold;
font-size: 38px;
padding-right: 80px;
padding-left: 70px;
}
.further {
overflow: hidden;
}
@media screen and (max-width: 640px) {
.about-image {
justify-content: center;
display: inline-block;
}
.further h1 {
padding-top: 200px;
display: inline;
}
}
马歇尔代码:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<div class="about-image">
<img class="resist" src="https://images.unsplash.com/photo-1554629947-334ff61d85dc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=376&q=80" width= "340px"
height= "480px"/>
<div class="overlay">
<a href="about.html">Caption</a>
</div>
</div>
<div class="further">
<h1>
Information written here</h1>
<h2> ⇨ More Information </h2>
<h2> ⇨ More Information</h2>
</div>
Xml结果:
@XmlRootElement(name = "classNameTAG")
@XmlAccessorType(XmlAccessType.FIELD)
public class ClassName {
@XmlElementWrapper(name="listTAG")
@XmlElement(name="itemTAG")
private List<ClassItem> items;
}
对我有用。
答案 3 :(得分:-1)
数组所接受的解决方案有效但会导致每个内部元素被命名:&lt; item&gt;
以下从此链接中获得的解决方案对我来说效果更好:
Is it possible to programmatically configure JAXB?
public class Wrapper<T> {
private List<T> items = new ArrayList<T>();
@XmlAnyElement(lax=true)
public List<T> getItems() {
return items;
}
}
//JAXBContext is thread safe and so create it in constructor or
//setter or wherever:
...
JAXBContext jc = JAXBContext.newInstance(Wrapper.class, clazz);
...
public String marshal(List<T> things, Class clazz) {
//configure JAXB and marshaller
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//Create wrapper based on generic list of objects
Wrapper<T> wrapper = new Wrapper<T>(things);
JAXBElement<Wrapper> wrapperJAXBElement = new JAXBElement<Wrapper>(new QName(clazz.getSimpleName().toLowerCase()+"s"), Wrapper.class, wrapper);
StringWriter result = new StringWriter();
//marshal!
m.marshal(wrapperJAXBElement, result);
return result.toString();
}
它不需要将列表转换为数组,但需要1个通用通用类。