Java 用于XML转换的XStream上的等效DROP_ROOT_模式
我怀疑是否可以忽略使用XStream将表单对象转换为xml的xml根元素,或者是否有任何方法可以用其他根元素替换根元素,我的意思是: 我有一个将自定义运行时创建的对象解析为XML的函数,类似于:Java 用于XML转换的XStream上的等效DROP_ROOT_模式,java,xml-parsing,marshalling,xstream,document-root,Java,Xml Parsing,Marshalling,Xstream,Document Root,我怀疑是否可以忽略使用XStream将表单对象转换为xml的xml根元素,或者是否有任何方法可以用其他根元素替换根元素,我的意思是: 我有一个将自定义运行时创建的对象解析为XML的函数,类似于: public static String entityToXML(GenericResponseObject entity) { XStream xstream = new XStream(new StaxDriver()); xstream.autodetectAnnotations
public static String entityToXML(GenericResponseObject entity) {
XStream xstream = new XStream(new StaxDriver());
xstream.autodetectAnnotations(true);
xstream.registerConverter(new GenericResponseAttributeConverter());
String xml = xstream.toXML(entity);
return xml;
}
response = new GenericResponseObject();
response.addAttribute("user", "alex");
response.addAttribute("otherAtt", "TEST");
System.out.println(XMLUtil.entityToXML(response));
为此,我搞得一团糟:
我有GenericResponseObject和GenericResponseAttribute类,其思想是让一个对象具有运行时所需的任意多个自定义属性:
@XStreamAlias("objectResult")
public class GenericResponseObject {
@XStreamAlias("attributes")
@XStreamImplicit
private ArrayList<GenericResponseAttribute> attributes;
public GenericResponseObject() {
this.attributes = new ArrayList();
}
public void addAttribute(String name, Object value) {
this.attributes.add(new GenericResponseAttribute(name, value));
}
}
如您所知,每个类都有用于别名和隐式列表的XStream注释,因此,让我向您展示我为GenericResponseAttribute类制作的自定义转换器:
public class GenericResponseAttributeConverter implements Converter {
@Override
public boolean canConvert(Class type) {
return type.equals(GenericResponseAttribute.class);
}
@Override
public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext mc) {
GenericResponseAttribute value = (GenericResponseAttribute)o;
writer.startNode(value.getName());
mc.convertAnother(value.getValue());
writer.endNode();
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext uc) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
因此,如果我在运行时构建一个GenericResponseObject,并使用静态方法将其解析为XML,则得到如下结果:
public static String entityToXML(GenericResponseObject entity) {
XStream xstream = new XStream(new StaxDriver());
xstream.autodetectAnnotations(true);
xstream.registerConverter(new GenericResponseAttributeConverter());
String xml = xstream.toXML(entity);
return xml;
}
response = new GenericResponseObject();
response.addAttribute("user", "alex");
response.addAttribute("otherAtt", "TEST");
System.out.println(XMLUtil.entityToXML(response));
println()函数的结果是:
<objectResult>
<attribute>
<user>hugo</user>
</attribute>
<attribute>
<otherAtt>TEST</otherAtt>
</attribute>
</objectResult>
雨果
试验
这几乎就是我想要的,但我确实需要省略GenericResponseAttribute类上的根元素,重要的是,对于我上面显示的根节点,总是只存在一个节点,即属性名称和属性值的内容。因此,如果我删除当前元素,它将始终是根元素,例如,我需要的previos XML结果是:
<objectResult>
<user>hugo</user>
<otherAtt>TEST</otherAtt>
</objectResult>
雨果
试验
我的需求非常基本,但我不知道如何正确,我已经搜索过了,HierarchycalStreamWriter类中似乎没有类似deletRootNode()或replaceRootNode()的方法,并且在GenericResponseAttribute中也没有可以使用的@xstreamNoot或@XStreamMakeRoot注释,所以,这就是我在这里提问的原因,如果你知道怎么做,请帮助我
谢谢。当我在将对象解析为XML后使用字符串替换时,我的意思是:
public static String entityToXML(Object entity) {
XStream xstream = new XStream(new StaxDriver());
xstream.autodetectAnnotations(true);
xstream.registerConverter(new GenericResponseAttributeConverter());
String xml = xstream.toXML(entity);
xml = xml.replace("<attribute>", "");
xml = xml.replace("</attribute>", "");
return xml;
}
公共静态字符串entityToXML(对象实体){
XStream XStream=newxstream(new statxdriver());
xstream.autodetectanotations(true);
registerConverter(新的GenericResponseAttributeConverter());
字符串xml=xstream.toXML(实体);
xml=xml.replace(“,”);
xml=xml.replace(“,”);
返回xml;
}
但是,这不是一个很酷的解决方案,如果你有另一个,请告诉我
谢谢。我提出的解决方案基于对类结构的修改,因为我找不到一种动态改变字段的方法,我认为这不是一种好的做法。实际上,xml结构必须始终相同,但是您可以跳过一些字段,在POJO中将它们设置为null 在我的解决方案中,我改变了问题的两类,最后给出了一个示例,说明如何将xml映射到相应的对象,并通过添加额外属性编辑对象,然后将其映射到具有新属性的xml字符串 以下是我的解决方案:
@XStreamAlias("attribute")
class GenericResponseAttribute {
@XStreamAlias("user")
private String user;
@XStreamAlias("otherAtt")
private String otherAtt;
public GenericResponseAttribute(String user, String otherAttr) {
super();
this.user = user;
this.otherAtt = otherAttr;
}
}
@XStreamAlias("objectResult")
class GenericResponseObject {
@XStreamAlias("attributes")
@XStreamImplicit
private ArrayList<GenericResponseAttribute> attributes;
public GenericResponseObject() {
this.attributes = new ArrayList<>();
}
public void addAttribute(String name, String otherAttr) {
this.attributes.add(new GenericResponseAttribute(name, otherAttr));
}
}
String xml=""+
"<objectResult>"+
" <attribute>"+
" <user>hugo</user>"+
" </attribute>"+
" <attribute>"+
" <otherAtt>TEST</otherAtt>"+
" </attribute>"+
"</objectResult>";
XStream stream=new XStream();
XStream.setupDefaultSecurity(stream);
stream.autodetectAnnotations(true);
stream.addPermission(AnyTypePermission.ANY);
stream.autodetectAnnotations(true);
stream.allowTypes(new Class[] {GenericResponseObject.class});
stream.addImplicitCollection(GenericResponseObject.class, "attributes", GenericResponseAttribute.class);
stream.alias("objectResult", GenericResponseObject.class);
GenericResponseObject obj = (GenericResponseObject) stream.fromXML(xml);
obj.addAttribute("another", "3");
String xml2 = stream.toXML(obj);
System.out.println(xml2);
@XStreamAlias(“属性”)
类GenericResponseAttribute{
@XStreamAlias(“用户”)
私有字符串用户;
@XStreamAlias(“其他ATT”)
私有字符串otherAtt;
公共GenericResponseAttribute(字符串用户、字符串其他属性){
超级();
this.user=用户;
this.otherAtt=otherAttr;
}
}
@XStreamAlias(“objectResult”)
类GenericResponseObject{
@XStreamAlias(“属性”)
@XStreamImplicit
私有数组列表属性;
公共一般响应对象(){
this.attributes=new ArrayList();
}
public void addAttribute(字符串名称、字符串其他属性){
add(新的GenericResponseAttribute(name,otherAttr));
}
}
字符串xml=“”+
""+
" "+
“雨果”+
" "+
" "+
“测试”+
" "+
"";
XStream stream=新的XStream();
setupDefaultSecurity(stream);
流。自动检测旋转(真);
stream.addPermission(AnyTypePermission.ANY);
流。自动检测旋转(真);
allowTypes(新类[]{GenericResponseObject.Class});
addImplicitCollection(GenericResponseObject.class,“属性”,GenericResponseAttribute.class);
别名(“objectResult”,GenericResponseObject.class);
GenericResponseObject obj=(GenericResponseObject)stream.fromXML(xml);
对象添加属性(“另一”、“3”);
字符串xml2=stream.toXML(obj);
System.out.println(xml2);
+可以工作,但在xml太大的情况下这样做是不好的