Java 用于XML转换的XStream上的等效DROP_ROOT_模式

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

我怀疑是否可以忽略使用XStream将表单对象转换为xml的xml根元素,或者是否有任何方法可以用其他根元素替换根元素,我的意思是:

我有一个将自定义运行时创建的对象解析为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));
为此,我搞得一团糟:

我有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太大的情况下这样做是不好的