Как конвертировать XML в java.util.Map и наоборот - PullRequest
65 голосов
/ 08 октября 2009

Я ищу легкий API (предпочтительный отдельный класс) для преобразования

Map<String,String> map = new HashMap<String,String();

в xml и, наоборот, преобразовать XML обратно в карту.

пример:

Map<String,String> map = new HashMap<String,String();
map.put("name","chris");
map.put("island","faranga");

MagicAPI.toXML(map,"root");

результат:

<root>
  <name>chris</chris>
  <island>faranga</island>
</root>

и обратно:

Map<String,String> map = MagicAPI.fromXML("...");

Я не хочу использовать JAXB или API преобразования JSON . Он не должен заботиться о вложенных картах или атрибутах или о чем-то еще, просто этот простой случай. Есть предложения?


Редактировать : Я создал образец рабочей копии и вставки. Благодаря fvu и Michal Bernhard .

Загрузите последнюю платформу XStream , достаточно «только ядро».

Map<String,Object> map = new HashMap<String,Object>();
map.put("name","chris");
map.put("island","faranga");

// convert to XML
XStream xStream = new XStream(new DomDriver());
xStream.alias("map", java.util.Map.class);
String xml = xStream.toXML(map);

// from XML, convert back to map
Map<String,Object> map2 = (Map<String,Object>) xStream.fromXML(xml);

Никаких преобразователей или чего-либо еще не требуется. Достаточно просто xstream-x.y.z.jar .

Ответы [ 12 ]

0 голосов
/ 20 июня 2018

В моем случае я конвертирую DBresponse в XML в Camel ctx. Исполнитель JDBC возвращает ArrayList (строки) с LinkedCaseInsensitiveMap (одна строка). Задача - создать объект XML на основе DBResponce.

import java.io.StringWriter;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.springframework.util.LinkedCaseInsensitiveMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class ConvertDBToXMLProcessor implements Processor {

    public void process(List body) {

        if (body instanceof ArrayList) {
            ArrayList<LinkedCaseInsensitiveMap> rows = (ArrayList) body;

            DocumentBuilder builder = null;
            builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document document = builder.newDocument();
            Element rootElement = document.createElement("DBResultSet");

            for (LinkedCaseInsensitiveMap row : rows) {
                Element newNode = document.createElement("Row");
                row.forEach((key, value) -> {
                    if (value != null) {
                        Element newKey = document.createElement((String) key);
                        newKey.setTextContent(value.toString());
                        newNode.appendChild(newKey);
                    }
                });
                rootElement.appendChild(newNode);
            }
            document.appendChild(rootElement);


            /* 
            * If you need return string view instead org.w3c.dom.Document
            */
            StringWriter writer = new StringWriter();
            StreamResult result = new StreamResult(writer);
            DOMSource domSource = new DOMSource(document);
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer transformer = tf.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
            transformer.transform(domSource, result);

            // return document
            // return writer.toString()

        }
    }
}
0 голосов
/ 24 мая 2017

Теперь 2017, последняя версия XStream требует конвертера, чтобы он работал так, как вы ожидаете.

Конвертер поддерживает вложенную карту:

public class MapEntryConverter implements Converter {

    @Override
    public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext marshallingContext) {
        AbstractMap map = (AbstractMap) value;
        for (Object obj : map.entrySet()) {
            Map.Entry entry = (Map.Entry) obj;
            writer.startNode(entry.getKey().toString());
            Object val = entry.getValue();
            if (val instanceof Map) {
                marshal(val, writer, marshallingContext);
            } else if (null != val) {
                writer.setValue(val.toString());
            }
            writer.endNode();
        }
    }

    @Override
    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext unmarshallingContext) {
        Map<String, Object> map = new HashMap<>();

        while(reader.hasMoreChildren()) {
            reader.moveDown();

            String key = reader.getNodeName(); // nodeName aka element's name
            String value = reader.getValue().replaceAll("\\n|\\t", "");
            if (StringUtils.isBlank(value)) {
                map.put(key, unmarshal(reader, unmarshallingContext));
            } else {
                map.put(key, value);
            }

            reader.moveUp();
        }

        return map;
    }

    @Override
    public boolean canConvert(Class clazz) {
        return AbstractMap.class.isAssignableFrom(clazz);
    }
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...