Xml to hashmap java

Как конвертировать XML в java.util.Map и наоборот

Я не хочу использовать JAXB или API конверсии JSON. Он не должен заботиться о вложенных картах или атрибутах или что-то еще, просто в этом простом случае. Любые предложения? Изменить. Я создал рабочую копию и вставьте образец. Благодаря fvu и Михал Бернхард. Загрузите последнюю инфраструктуру XStream, достаточно «ядра».

Map map = new HashMap(); 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 map2 = (Map) xStream.fromXML(xml); 

Ну, я протестировал несколько версий от 1.2 (более ранняя версия не прошла десериализацию / демаршал) до последней версии 1.4.6, и всегда нужен специальный конвертер карт, как в моем ответе ниже, чтобы получить желаемый результат. В противном случае он выводит то, что говорит Арджан в комментарии выше.

11 ответов

Обновлено: я добавил немаршальную часть в соответствии с запросом в комментариях.

import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import java.util.AbstractMap; import java.util.HashMap; import java.util.Map; public class Test < public static void main(String[] args) < Mapmap = new HashMap(); map.put("name","chris"); map.put("island","faranga"); XStream magicApi = new XStream(); magicApi.registerConverter(new MapEntryConverter()); magicApi.alias("root", Map.class); String xml = magicApi.toXML(map); System.out.println("Result of tweaked XStream toXml()"); System.out.println(xml); Map extractedMap = (Map) magicApi.fromXML(xml); assert extractedMap.get("name").equals("chris"); assert extractedMap.get("island").equals("faranga"); > public static class MapEntryConverter implements Converter < public boolean canConvert(Class clazz) < return AbstractMap.class.isAssignableFrom(clazz); >public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) < 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 ( null != val ) < writer.setValue(val.toString()); >writer.endNode(); > > public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) < Mapmap = new HashMap(); while(reader.hasMoreChildren()) < reader.moveDown(); String key = reader.getNodeName(); // nodeName aka element name String value = reader.getValue(); map.put(key, value); reader.moveUp(); >return map; > > > 

XStream xs = new XStream (новый DomDriver («UTF-8», новый XmlFriendlyReplacer («_-«, «_»))); // для правильной обработки подчеркивания

Читайте также:  Fixed vs sticky

Я пробовал приведенный выше код в случае, когда на карте есть объекты домена, String, Boolean и т. Д., Но не конвертируются в xml. Можете ли вы подсказать, что я делаю неправильно.

Здесь конвертер для XStream, включая unmarshall

public class MapEntryConverter implements Converter < public boolean canConvert(Class clazz) < return AbstractMap.class.isAssignableFrom(clazz); >public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) < AbstractMapmap = (AbstractMap) value; for (Entry entry : map.entrySet()) < writer.startNode(entry.getKey().toString()); writer.setValue(entry.getValue().toString()); writer.endNode(); >> public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) < Mapmap = new HashMap(); while(reader.hasMoreChildren()) < reader.moveDown(); map.put(reader.getNodeName(), reader.getValue()); reader.moveUp(); >return map; > 

Человек, я должен был написать этот глупый конвертер 500 раз. Вы сказали бы, что я учусь! Каждый раз, когда мне приходится подбирать странную карту, я получаю ответ. Я бы плюс десять, если бы мог! 😉

Как насчет XStream? Не 1 класс, а 2 баночки для многих вариантов использования, включая ваш, очень простой в использовании, но достаточно мощный.

Источник

JAXB – Marshal and Unmarshal HashMap in Java

We know that JAXB(Java Architecture for XML Binding) allows Java developers to map Java classes to XML representations. JAXB provides two main features: the ability to marshal Java objects into XML and the inverse, i.e. to unmarshal XML back into Java objects. JAXB mostly is used while implementing webservices or any other such client interface for an application where data needs to be transferred in XML format instead of HTML format which is default in case of visual client like web browsers.

A good example is facebook APIs. Facebook has exposed its services through some open endpoints in form of RESTful webservices where you hit a URL and post some parameters, and API return you the data in xml format. Now it is upto you, how you use that data.

In this post, I am giving an example of marshalling and unmarshalling of Map object e.g. HashMap . These map objects are usually represent the mapping between some simple keys to complex data.

1) JAXB Maven Dependencies

To run JAXB examples, we need to add run time dependencies like below.

 com.sun.xml.bind jaxb-core 2.2.8-b01  com.sun.xml.bind jaxb-impl 2.2-promoted-b65  

I have created a model class “ Employee.java ” which has some common fields. I want to build code which could parse map of objects where key is sequence code and value is Employee object itself.

@XmlRootElement(name = "employee") @XmlAccessorType (XmlAccessType.FIELD) public class Employee < private Integer id; private String firstName; private String lastName; private double income; //Getters and Setters >
import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement (name="employees") @XmlAccessorType(XmlAccessType.FIELD) public class EmployeeMap < private MapemployeeMap = new HashMap(); public Map getEmployeeMap() < return employeeMap; >public void setEmployeeMap(Map employeeMap) < this.employeeMap = employeeMap; >>

3) Marshal Map to XML Example

Java example to marshal or convert java map to xml representation. In below example code, I am writing the map of employees first in console, and then in a file.

public static void main(String[] args) throws JAXBException < HashMapmap = new HashMap(); Employee emp1 = new Employee(); emp1.setId(1); emp1.setFirstName("Lokesh"); emp1.setLastName("Gupta"); emp1.setIncome(100.0); Employee emp2 = new Employee(); emp2.setId(2); emp2.setFirstName("John"); emp2.setLastName("Mclane"); emp2.setIncome(200.0); map.put( 1 , emp1); map.put( 2 , emp2); //Add employees in map EmployeeMap employeeMap = new EmployeeMap(); employeeMap.setEmployeeMap(map); /******************** Marshalling example *****************************/ JAXBContext jaxbContext = JAXBContext.newInstance(EmployeeMap.class); Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); jaxbMarshaller.marshal(employeeMap, System.out); jaxbMarshaller.marshal(employeeMap, new File("c:/temp/employees.xml")); > Output:    1 1 Lokesh Gupta 100.0   2 2 John Mclane 200.0     

4) Unmarshal XML to Map Example

Java example to convert xml to Java map object. Let’s see the example of our EmployeeMap class.

private static void unMarshalingExample() throws JAXBException < JAXBContext jaxbContext = JAXBContext.newInstance(EmployeeMap.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); EmployeeMap empMap = (EmployeeMap) jaxbUnmarshaller.unmarshal( new File("c:/temp/employees.xml") ); for(Integer empId : empMap.getEmployeeMap().keySet()) < System.out.println(empMap.getEmployeeMap().get(empId).getFirstName()); System.out.println(empMap.getEmployeeMap().get(empId).getLastName()); >> Output: Lokesh Gupta John Mclane

To download the sourcecode of above example follow below link.

Источник

Блог

Расположение полей и их соответствующих значений может находиться либо в одной строке, либо в другой строке.

Мне нужно написать Java-код, который принимает эту строку в качестве входных данных и анализирует каждый ТЕГ от начала до конца и сохраняет его поле и значения в новой паре Ключ-значение HashMap для каждого встречающегося тега.

Я ожидаю, что результат в виде —

 HashMap 1 for Tag1 - (F1, V1), (F2, V2), (F3, V3), (F4, V4). HashMap 2 for Tag2 - (F1, V1), (F2, V2), (F3, V3), (F4, V4). HashMap 3 for Tag3 - (F1, V1), (F2, V2), (F3, V3), (F4, V4). 

Imp — Поля и значения могут быть в разных строках.

Будем признательны за любую помощь.

Комментарии:

1. Пробел после < не допускается в XML.

2. вам нужно использовать анализатор XML, на ум приходят JDOM и SAX

Ответ №1:

Я написал простое решение с Dom4j и Jaaxen, я также добавил корень в ваш документ, который можно удалить после обработки ввода, если вы хотите:

 package com.aissaoui.iqbal.xml.utils; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Node; public class Main < public static void main(String[] args) < StringBuilder sb = new StringBuilder(); sb.append(""V1" F2="V2" F3="V3" F4="V4"/>); sb.append(" F1="V1" "); sb.append(" F2="V2" "); sb.append(" F3="V3" F4="V4"/>); sb.append(" F1="V1" "); sb.append(" F2="V2" "); sb.append(" F3="V3" F4="V4""); sb.append(" F5="V5""); sb.append("/>"); String text = sb.toString(); try < Document document = DocumentHelper.parseText(text); String xPath = "/root/*"; ListNode> list = document.selectNodes(xPath); MapString,String> map = new HashMap<>(); for(Node n:list)< System.out.println("Tag: " n.getName()); MapString,String> hmAttributes = new HashMap<>(); ListAttribute> lAttributes = ((Element) n).attributes(); for(Attribute attr:lAttributes) < hmAttributes.put(attr.getName(), attr.getValue()); >System.out.println("Attributes: " hmAttributes.toString()); > > catch (DocumentException ex) < Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); > > > 
  dependency> groupId>jaxen groupId> artifactId>jaxen artifactId> version>1.1.1 version> dependency>  dependency> groupId>dom4j groupId> artifactId>dom4j artifactId> version>1.6.1 version> dependency>  

Источник

JAXB, Custom XML to Java Map using XMLAdapter

In some cases XML structure that is specific to a Java container is very different, e.g. Map. And we want to bind our Java classes with a customized and more readable XML, JAXB XmlJavaTypeAdapter annotation comes very handy in such situations. Such mappings require an adapter class, written as an extension of XmlAdapter, and XmlJavaTypeAdapter annotation suggests JAXB to use the adapter at specified location:

For illustration purpose, we’ll have a custom XML:

And this is our JAXB annotated message class(minimal):

And the profile class with required annotations, note that we have a HashMap of Message where message id is the key and Message object itself as a value. Also note the use of @XmlJavaTypeAdapter which provides mapping between custom XML and HashMap during the process of marshaling/ unmarshaling. Going forward we’ll see how we are going to achieve that.

@XmlRootElement(name="profile") public class Profile < @XmlElement @XmlJavaTypeAdapter(MessageAdapter.class) private HashMapmessages; public Profile()<> public Profile(HashMap b ) < messages = b; >>

To fill the gap we need to provide something that JAXB knows how to handle, we can use a wrapper class which contains Array of objects of type Messagse.

Now you must have got a fair idea that how JAXB is going to read XML messages to Message array back and forth. Let’s write an adapter to map our Array to a HasMap.

public class MessageAdapter extends XmlAdapter> < @Override public Mapunmarshal( Messages value ) < Mapmap = new HashMap(); for( Message msg : value.messages ) map.put( msg.getId(), msg ); return map; > @Override public Messages marshal( Map map ) < Messages msgCont = new Messages(); Collectionmsgs = map.values(); msgCont.messages = msgs.toArray(new Message[msgs.size()]); return msgCont; > >

And here is the test class to assert our assumptions:

public class XmlAdapterTest extends TestCase < public void testAdapter() throws Exception < InputStream is = this.getClass().getClassLoader().getResourceAsStream("profile.xml"); if (is != null) < JAXBContext jc; try < //test unmarshaling jc = JAXBContext.newInstance(Profile.class.getPackage().getName()); Unmarshaller u = jc.createUnmarshaller(); Profile profile = (Profile) u.unmarshal(is); assertNotNull(profile.getMessages()); assertEquals( 2, profile.getMessages().size()); //test marshaling Marshaller marshaller=jc.createMarshaller(); File xmlDocument = new File("output.xml"); marshaller.marshal(profile, new FileOutputStream(xmlDocument)); assertTrue(xmlDocument.length() >0); xmlDocument.delete(); > catch (JAXBException e) < e.printStackTrace(); fail(); >> > >

Still need the source code, find here: jaxb-typeadapter source, Sushant

Источник

Блог

Расположение полей и их соответствующих значений может находиться либо в одной строке, либо в другой строке.

Мне нужно написать Java-код, который принимает эту строку в качестве входных данных и анализирует каждый ТЕГ от начала до конца и сохраняет его поле и значения в новой паре Ключ-значение HashMap для каждого встречающегося тега.

Я ожидаю, что результат в виде —

 HashMap 1 for Tag1 - (F1, V1), (F2, V2), (F3, V3), (F4, V4). HashMap 2 for Tag2 - (F1, V1), (F2, V2), (F3, V3), (F4, V4). HashMap 3 for Tag3 - (F1, V1), (F2, V2), (F3, V3), (F4, V4). 

Imp — Поля и значения могут быть в разных строках.

Будем признательны за любую помощь.

Комментарии:

1. Пробел после < не допускается в XML.

2. вам нужно использовать анализатор XML, на ум приходят JDOM и SAX

Ответ №1:

Я написал простое решение с Dom4j и Jaaxen, я также добавил корень в ваш документ, который можно удалить после обработки ввода, если вы хотите:

 package com.aissaoui.iqbal.xml.utils; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Node; public class Main < public static void main(String[] args) < StringBuilder sb = new StringBuilder(); sb.append(""V1" F2="V2" F3="V3" F4="V4"/>); sb.append(" F1="V1" "); sb.append(" F2="V2" "); sb.append(" F3="V3" F4="V4"/>); sb.append(" F1="V1" "); sb.append(" F2="V2" "); sb.append(" F3="V3" F4="V4""); sb.append(" F5="V5""); sb.append("/>"); String text = sb.toString(); try < Document document = DocumentHelper.parseText(text); String xPath = "/root/*"; ListNode> list = document.selectNodes(xPath); MapString,String> map = new HashMap<>(); for(Node n:list)< System.out.println("Tag: " n.getName()); MapString,String> hmAttributes = new HashMap<>(); ListAttribute> lAttributes = ((Element) n).attributes(); for(Attribute attr:lAttributes) < hmAttributes.put(attr.getName(), attr.getValue()); >System.out.println("Attributes: " hmAttributes.toString()); > > catch (DocumentException ex) < Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); > > > 
  dependency> groupId>jaxen groupId> artifactId>jaxen artifactId> version>1.1.1 version> dependency>  dependency> groupId>dom4j groupId> artifactId>dom4j artifactId> version>1.6.1 version> dependency>  

Источник

Оцените статью