一种在java中将数据序列化为具有属性的XML的方法

一种在java中将数据序列化为具有属性的XML的方法,java,serialization,deserialization,Java,Serialization,Deserialization,当我调用api时,会得到如下xml响应。 我需要将其反序列化为一个对象,然后将其序列化回相同格式的xml <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Person version= "xyz"> <properties> <name> John</name>

当我调用api时,会得到如下xml响应。 我需要将其反序列化为一个对象,然后将其序列化回相同格式的xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Person version= "xyz">
    <properties>
        <name> John</name>
        <city>nyc</city>
    </properties>
</Person>

约翰
纽约市
我面临两个挑战

1> 属性有一个变量列表。我需要将其序列化为一个映射。(key:name->value:John、key:city->value:nyc等)

2> 当我将Person对象序列化回XML时,如何添加
version=“xyz”
属性


有人能帮我吗?

您可以使用JAXB和
@xmlanyement
来支持具有任意名称的元素

以下内容在Java8中本机运行。对于Java 7,需要将
toString()
中的流逻辑更改为常规
For
循环。对于删除了JAXB的Java9+,需要一个JAXB库

@XmlRootElement(name=“Person”)
@XmlAccessorType(XmlAccessType.NONE)
班主任{
私有字符串版本;
私有财产清单;
@XmlAttribute
公共字符串getVersion(){
返回此.version;
}
公共void setVersion(字符串版本){
this.version=版本;
}
@XmlElementWrapper(name=“properties”)
@XmlAnyElement
公共列表getProperties(){
返回此文件。属性;
}
公共void集合属性(列表属性){
这个。属性=属性;
}
公共void addProperty(字符串名称、字符串值){
试一试{
元素elem=DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument().createElement(名称);
元素setTextContent(值);
if(this.properties==null)
this.properties=new ArrayList();
此.properties.add(elem);
}捕获(ParserConfiguration异常e){
抛出新的非法状态异常(e);
}
}
@凌驾
公共字符串toString(){
String propertiesAsString=this.properties.stream()
.map(e->e.getLocalName()+“:\”+e.getTextContent()+“\”)
.collect(收集器.连接(“,”,“[”,“]));
返回“Person[version=“+this.version+”,properties=“+propertiesAsString+””;
}
}
试验

Person-Person=新的Person();
person.setVersion(“xyz”);
个人。添加财产(“姓名”、“约翰”);
个人。addProperty(“城市”、“纽约市”);
JAXBContext JAXBContext=JAXBContext.newInstance(Person.class);
Marshaller=jaxbContext.createMarshaller();
setProperty(marshaller.JAXB_格式的_输出,Boolean.TRUE);
StringWriter xml=新的StringWriter();
marshaller.marshall(person,xml);
System.out.println(xml);
Unmarshaller Unmarshaller=jaxbContext.createUnmarshaller();
Person person2=(Person)unmarshaller.unmarshal(新StringReader(xml.toString());
系统输出打印LN(人员2);
输出


约翰
纽约市
个人[版本=xyz,属性=[姓名:“约翰”,城市:“纽约”]]

您可以使用JAXB和
@xmlanyement
来支持具有任意名称的元素

以下内容在Java8中本机运行。对于Java 7,需要将
toString()
中的流逻辑更改为常规
For
循环。对于删除了JAXB的Java9+,需要一个JAXB库

@XmlRootElement(name=“Person”)
@XmlAccessorType(XmlAccessType.NONE)
班主任{
私有字符串版本;
私有财产清单;
@XmlAttribute
公共字符串getVersion(){
返回此.version;
}
公共void setVersion(字符串版本){
this.version=版本;
}
@XmlElementWrapper(name=“properties”)
@XmlAnyElement
公共列表getProperties(){
返回此文件。属性;
}
公共void集合属性(列表属性){
这个。属性=属性;
}
公共void addProperty(字符串名称、字符串值){
试一试{
元素elem=DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument().createElement(名称);
元素setTextContent(值);
if(this.properties==null)
this.properties=new ArrayList();
此.properties.add(elem);
}捕获(ParserConfiguration异常e){
抛出新的非法状态异常(e);
}
}
@凌驾
公共字符串toString(){
String propertiesAsString=this.properties.stream()
.map(e->e.getLocalName()+“:\”+e.getTextContent()+“\”)
.collect(收集器.连接(“,”,“[”,“]));
返回“Person[version=“+this.version+”,properties=“+propertiesAsString+””;
}
}
试验

Person-Person=新的Person();
person.setVersion(“xyz”);
个人。添加财产(“姓名”、“约翰”);
个人。addProperty(“城市”、“纽约市”);
JAXBContext JAXBContext=JAXBContext.newInstance(Person.class);
Marshaller=jaxbContext.createMarshaller();
setProperty(marshaller.JAXB_格式的_输出,Boolean.TRUE);
StringWriter xml=新的StringWriter();
marshaller.marshall(person,xml);
System.out.println(xml);
Unmarshaller Unmarshaller=jaxbContext.createUnmarshaller();
Person person2=(Person)unmarshaller.unmarshal(新StringReader(xml.toString());
系统输出打印LN(人员2);
输出


约翰
纽约市
个人[版本=xyz,属性=[姓名:“约翰”,城市:“纽约”]]