我需要在下面的代码片段中生成和XML一样,除了 firstName , middleName 和 lastName 之外还会有很多(大约50个) )玩家的元素。对于这个XML,我需要使用POJO来使用JAXB生成XML。因为,玩家元素不仅具有值,而且还具有属性,并且根据我的理解,我不能在原始类型的玩家类中声明属性,而是每个元素都是一个类。
<Players>
<Player>
<FirstName id="001">Mahendra</FirstName>
<MiddleName id="002">Singh</MiddleName>
<LastName id="003">Dhoni</LastName>
</Player>
</Player>
但我不想创建这50个类,而是我认为有一个类可以用于播放器的所有属性,但在这种情况下生成的XML将如下所示:
<Players>
<Player>
<Property id="001">
<Name>FirstName</Name>
<Value>Mahendra</Value>
</Property>
<Property id="002">
<Name>MiddleName</Name>
<Value>Sing</Value>
</Property>
<Property id="003">
<Name>LastName</Name>
<Value>Dhoni</Value>
</Property>
</Player>
</Player>
我在这里想要的是一种为'Property'标记赋予名称的方法,该属性具有Property类中的'Name'属性的值,而不是具有两个子元素viz。 “名称”和“价值”仅显示“价值”的值。我的意思是如何才能获得
<FirstName id="001">Mahendra</FirstName>
除了
<Property id="001">
<Name>FirstName</Name>
<Value>Mahendra</Value>
</Property>
将POJO作为:
Players.java
class Players
{
List<Player> player;
//and getter setter
}
Player.java
class Player
{
List<Property> property;
// and getter setter
}
Property.java
class Property
{
String name;
String value;
String id;
}
我没有在这里使用任何注释,因为我需要知道放在那里得到我想要的东西。 :)
答案 0 :(得分:0)
此时你可能已经解决了这个问题,这是一个有趣的练习,我有一些空闲时间。
在名为StepByStep的com.quick包中创建一个类,在连接之前删除所有IDE生成的代码(清空文件)。
首先再次添加包
package com.quick;
首先添加导入
import java.io.*;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.w3c.dom.Element;
现在,添加一些上课
class Player {List<Property> property = new ArrayList<>();}
class Property {
String id, name, value;
public Property(String id, String name, String value) {
this.id = id;
this.name = name;
this.value = value;
}
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD) // or write the get and set methods
class Players {
@XmlJavaTypeAdapter(PlayerTypeAdapter.class) // dont worry about this line
List<Player> player;
}
现在,添加XmlAdapter类(PlayerTypeAdapter),这是最重要的部分,如果您已经知道@XmlJavaTypeAdapter是如何工作的,并且您只想知道如何将任意xml放在元素焦点中
class PlayerTypeAdapter extends XmlAdapter<Object, Player> {
private DocumentBuilder documentBuilder;
public PlayerTypeAdapter() {
try {
documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
} catch (Exception e) {
}
}
@Override
public Player unmarshal(Object v) throws Exception {
Player p = new Player();
NodeList c = ((Element) v).getChildNodes();
for (int i = 0; i < c.getLength(); i++) {
Node n = c.item(i);
if (!(n instanceof Element)) continue;
Element e = (Element) n;
p.property.add(new Property(e.getAttribute("id"),
e.getTagName(), e.getTextContent()));
}
return p;
}
@Override
public Object marshal(Player v) throws Exception {
Document document = documentBuilder.newDocument();
Element root = document.createElement("dummy");
if (v.property != null) for (Property p : v.property) {
Element propertyNode = document.createElement(p.name);
propertyNode.setAttribute("id", p.id);
propertyNode.setTextContent(p.value);
root.appendChild(propertyNode);
}
return root;
}
}
最后使用main方法添加StepByStep类(只是为了测试我们的代码)
public class StepByStep {
public static void main(String[] args) throws JAXBException {
// context, marshaller and unmarshaller
JAXBContext context = JAXBContext.newInstance(Players.class, Player.class, Property.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Unmarshaller unmarshaller = context.createUnmarshaller();
// lets fill dummy players
Players p = new Players();
p.player = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Player e = new Player();
e.property.add(new Property("001", "FirstName", "Mahendra"));
e.property.add(new Property("002", "MiddleName", "Sing"));
e.property.add(new Property("003", "LastName", "Dhoni"));
p.player.add(e);
}
// marshal p (original)
ByteArrayOutputStream os1 = new ByteArrayOutputStream();
marshaller.marshal(p, os1);
byte[] ba1 = os1.toByteArray();
Players q = (Players) unmarshaller.unmarshal(new ByteArrayInputStream(ba1));
// marshal q (copy)
ByteArrayOutputStream os2 = new ByteArrayOutputStream();
marshaller.marshal(q, os2);
byte[] ba2 = os2.toByteArray();
// both q and p should be the same
System.out.println(new String(ba1));
System.out.println(new String(ba2));
}
}