Xstream隐式映射作为根元素的属性

时间:2011-09-30 08:47:07

标签: java xml xstream

我正在尝试使用XStream找到将地图转换为根元素属性的解决方案。

我不认为这是可能的,但这是我尝试过的。

我创建了一个自定义转换器并将其附加到根对象,然后在转换器中我可以访问我想要转换为属性的地图,我遍历地图并使用编写器将attirbute写入节点.addAttribute(entry.getKey(),entry.getValue());这实际上确实将属性写入根节点,例如

这种方法的问题在于它不处理文档的其余部分,它只是在处理完地图后停止,为了让它工作我需要一些方法让默认转换器重新控制并完成模特。

我一直试图使用的第二个解决方案就是为地图创建一个自定义转换器,这个方法的问题是我无法获取根元素的句柄,所以我无法写入它,是否可以通过这种方式访问​​根元素?

谢谢, 乔恩

1 个答案:

答案 0 :(得分:1)

创建一个转换器,用于写出地图并使用反射转换器重新编组对象:

static class MyConverter implements Converter {

    private final Map<String, String> attributes;

    private final Class<?> clazz;

    private final Mapper mapper;

    private final ReflectionProvider reflectionProvider;

    public MyConverter(Mapper mapper,
            ReflectionProvider reflectionProvider, Class<?> clazz,
            Map<String, String> attributes) {
        super();
        this.mapper = mapper;
        this.reflectionProvider = reflectionProvider;
        this.attributes = attributes;
        this.clazz = clazz;
    }

    @Override
    public boolean canConvert(Class cls) {
        return cls == clazz;
    }

    @Override
    public void marshal(Object value, HierarchicalStreamWriter writer,
            MarshallingContext context) {
        for (String key : attributes.keySet()) {
            writer.addAttribute(key, attributes.get(key));
        }

        Converter converter = new ReflectionConverter(mapper,
                reflectionProvider);
        context.convertAnother(p, converter);
    }

    @Override
    public Object unmarshal(HierarchicalStreamReader arg0,
            UnmarshallingContext arg1) {
        // TODO Auto-generated method stub
        return null;
    }

}

从XStream实例中检索Mapper和ReflectionProvider实例,并注册一个具有所有必要设置的转换器:

    XStream xs = new XStream(new DomDriver());
    Mapper mapper = xs.getMapper();
    ReflectionProvider reflectionProvider = xs.getReflectionProvider();
    xs.alias("youralias", YourRoot.class);
    xs.registerConverter(new MyConverter(mapper, reflectionProvider,
            YourRoot.class, map));

    System.out.println(xs.toXML(yourRoot));