使用xstream将键值xml对映射到java映射

时间:2013-05-09 21:50:22

标签: java xml xstream

我正在尝试将xml文件转换为java map。 的 XML

<Person>
   <ID>123</ID>
   <Demographics>
   <LastName>ABC</LastName>
   <FirstName>XYZ</FirstName>
   </Demographics>
   <Married>YES</Married>
</Person>

XStream代码如下:

    final XStream xstream = new XStream();
    xstream.alias("Person", Map.class);
    xstream.alias("Demographics", Map.class);
    xstream.registerConverter(new MapEntryConverter());

    final Map<String, Object> map2 = (Map<String, Object>) xstream.fromXML(xml);//where xml is above defined string.

自定义MapEntryConverter是:

public class MapEntryConverter implements Converter
{
    public boolean canConvert(final Class clazz)
    {
        return AbstractMap.class.isAssignableFrom(clazz);
    }

    public void marshal(final Object value, final HierarchicalStreamWriter writer, final MarshallingContext context)
    {
        final AbstractMap<String, String> map = (AbstractMap<String, String>) value;
        for (final Entry<String, String> entry : map.entrySet())
        {
            writer.startNode(entry.getKey().toString());
            writer.setValue(entry.getValue().toString());
            writer.endNode();
        }
    }

    public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context)
    {
        final Map<String, String> map = new HashMap<String, String>();
        while (reader.hasMoreChildren())
        {
            reader.moveDown();
            map.put(reader.getNodeName(), reader.getValue());
            reader.moveUp();
        }
        return map;
    }
}

因此,地图现在只包含ID和Married作为键值对。它没有将Demographics父级转换为相应的名称值对。

我希望将所有标记名称作为键,将其值作为地图值。

1 个答案:

答案 0 :(得分:2)

利用convertAnother上的MarshallingContext方法来处理数据的分层性质,例如:

public class MapEntryConverter implements Converter {

    public boolean canConvert(final Class clazz) {
        return Map.class.isAssignableFrom(clazz);
    }

    public void marshal(final Object value, final HierarchicalStreamWriter writer, final MarshallingContext context) {
        Map<String, Object> map = (Map<String, Object>) value;
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (entry.getValue() instanceof Map) {
                writer.startNode(entry.getKey());
                context.convertAnother(entry.getValue());
                writer.endNode();
            } else {
                writer.startNode(entry.getKey());
                writer.setValue(entry.getValue().toString());
                writer.endNode();
            }
        }
    }

    public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) {
        Map<String, Object> map = new HashMap<String, Object>();
        while (reader.hasMoreChildren()) {
            reader.moveDown();
            if (reader.hasMoreChildren()) {
                Map<String, Object> childMap = (Map<String, Object>) context.convertAnother(new HashMap<String, Object>(), Map.class);
                map.put(reader.getNodeName(), childMap);
            } else {
                map.put(reader.getNodeName(), reader.getValue());
            }

            reader.moveUp();
        }
        return map;
    }
}