用于XML转换的XStream上的等效DROP_ROOT_MODE

时间:2012-11-12 01:37:56

标签: java xml-parsing marshalling xstream document-root

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

我有一个函数将自定义运行时创建的对象解析为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;
}

为此,我弄得一团糟:

我有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));
    }
}

类GenericResponseAttribute:

@XStreamAlias("attribute")
public class GenericResponseAttribute {

    private String name;
    private Object value;

    public GenericResponseAttribute(String name, Object value) {
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Object getValue() {
        return this.value;
    }

    public void setValue(Object value) {
        this.value = 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,那么K就会出现类似的内容:

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>

我的需求非常基本,但我不知道如何正确,我已经搜索过,似乎在HierarchicalStreamWriter类中没有像deletRootNode()或replaceRootNode()那样的方法,并且没有@XStreamNoRoot或者我可以在GenericResponseAttribute中使用@XStreamMakeRoot注释,这就是我在这里问的原因,如果你知道怎么做,请帮助我。

感谢。

2 个答案:

答案 0 :(得分:2)

到目前为止,在将对象解析为XML后,我最终使用了String替换,我的意思是:

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;
}

但是,这不是一个很酷的解决方案,如果你有另一个,请告诉我。

感谢。

答案 1 :(得分:0)

我提出的解决方案基于对类结构的修改,因为我找不到动态改变字段的方法,我认为这不是一个好习惯。实际上,xml结构必须始终相同,但是您可以跳过某些字段,在POJO中将其设置为null

在我的解决方案中,我更改了问题的两个类别,最后有一个示例,说明了如何将xml映射到相应的对象并编辑该对象,添加一个额外的属性,然后将其映射到xml字符串。新属性

这是我的解决方法:

RepositoryConfigurationDelegate#registerRepositoriesIn