从属性文件中加载地图作为键。

huangapple go评论71阅读模式
英文:

Load map as a key from properties file

问题

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        Properties properties = new Properties();
        try (InputStream inputStream = Main.class.getResourceAsStream("student.properties")) {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

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

        properties.forEach((key, value) -> {
            String mapName = key.toString();
            if (mapName.startsWith("map name=")) {
                Map<String, String> studentInfo = new HashMap<>();
                String[] lines = value.toString().split("\\n");
                for (String line : lines) {
                    if (line.contains("value key=")) {
                        String[] parts = line.split("[<>]");
                        String propertyKey = parts[2];
                        String propertyValue = parts[4];
                        studentInfo.put(propertyKey, propertyValue);
                    }
                }
                studentMap.put(mapName.substring(10, mapName.length() - 1), studentInfo);
            }
        });

        List<Map<String, String>> studentList = new ArrayList<>(studentMap.values());

        // Print the list of student maps
        studentList.forEach(System.out::println);
    }
}

Please note that the provided code snippet assumes that the properties file is named "student.properties" and is located in the same directory as the Java source file. Make sure to adjust the code accordingly if the properties file is located elsewhere.

Also, ensure that the XML-like format in the properties file is well-formed. The given content in your example needs to be corrected to valid XML format.

英文:

How I can get a map as key from properties file and load in a list. For example I want to create a hashmap of student information from properties file. Property file can be like

&lt;map name=student1&gt;
&lt;value key=name&gt;abc&lt;/value&gt;
&lt;value key=age&gt;12&lt;/value&gt;
&lt;value key=gender&gt;male&lt;/value&gt;
&lt;map name=student2&gt;
&lt;value key=name&gt;xyz&lt;/value&gt;
&lt;value key=age&gt;15&lt;/value&gt;
&lt;value key=gender&gt;female&lt;/value&gt;
... 

I want to create the list of all these map using key like student1, student2 etc. How can we do it in simple java 8 project using properties file in a single load. I am sorry if I am asking any repeated question. I tried to search for my solution but didn't get it. Please help with the link if same question answered before.

答案1

得分: 1

如果我正确理解你的问题,你希望将XML配置反序列化为一个Map<String, User>,其中User具有任意字段。

你的配置文件缺少映射节点的闭合标签。
一旦你按照以下格式编写,你就可以轻松自动化解码过程:

<Config>
  <map name="student1">
    <value key="name">abc</value>
    <value key="age">12</value>
    <value key="gender">male</value>
  </map>

  <map name="student2">
    <value key="name">xyz</value>
    <value key="age">15</value>
    <value key="gender">female</value>
  </map>
</Config>

你可以使用javax.xml.parsers解决方案创建自定义的编组器:

try {
    final File configFile = Paths.get("C:/Development/file.xml").toFile();
    final DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    final DocumentBuilder dBuilder;

    dBuilder = dbFactory.newDocumentBuilder();

    final Document doc = dBuilder.parse(configFile);

    final NodeList nodeList = doc.getChildNodes();
    if (nodeList.getLength() == 0) {
        throw new IllegalArgumentException("Config is empty or incorrect.");
    }

    final NodeList elements = nodeList.item(0).getChildNodes();

    final Map<String, User> users = new HashMap<>();

    for (int i = 0; i < elements.getLength(); i++) {
        final Node item = elements.item(i);
        if (!"map".equals(item.getNodeName())) {
            continue;
        }

        final String key = item.getAttributes().getNamedItem("name").getNodeValue();

        final NodeList childNodes = item.getChildNodes();

        String name;
        String age;
        String gender;

        for (int j = 0; j < childNodes.getLength(); j++) {
            final Node childItem = childNodes.item(j);
            if (!"value".equals(childItem.getNodeName())) {
                continue;
            }

            final String fieldName = childItem.getAttributes().getNamedItem("key").getNodeValue();
            final String fieldValue = childItem.getTextContent();
            switch (fieldName) {
                case "name":
                    name = fieldValue;
                    break;
                case "age":
                    age = fieldValue;
                    break;
                case "gender":
                    gender = fieldValue;
                    break;
                default:
                    throw new IllegalArgumentException(String.format("Unknown user field %s", fieldName));
            }
        }
        
        users.put(key, new User(name, age, gender));
    }
} catch (final ParserConfigurationException | SAXException | IOException e) {
    throw new IllegalArgumentException("Error during config parsing");
}

EDIT:
由于主贴下的评论以及我无法在那里编写评论,我将在这里写:
配置属性文件是一种常用的键值对结构,以如下示例序列化为文件:

property.name=value
other.property.name=value

XML文件也是一种数据结构形式,尽管XML文件的可能性更广泛,提供更多的数据灵活性以及对象序列化。你的配置可以以属性格式、XML、JSON等形式存储。然而,你的数据类型表明需要使用比属性更复杂的数据存储结构。

英文:

If I understand question correctly, you want to unmarshall the XML configuration into a Map<String, User>, where User has arbitrary fields.

Your config file is missing closure of the map nodes.
Once you have it in the following format, you will be able to easily automate the decoding process:

&lt;Config&gt;
&lt;map name=&quot;student1&quot;&gt;
&lt;value key=&quot;name&quot;&gt;abc&lt;/value&gt;
&lt;value key=&quot;age&quot;&gt;12&lt;/value&gt;
&lt;value key=&quot;gender&quot;&gt;male&lt;/value&gt;
&lt;/map&gt;
&lt;map name=&quot;student2&quot;&gt;
&lt;value key=&quot;name&quot;&gt;xyz&lt;/value&gt;
&lt;value key=&quot;age&quot;&gt;15&lt;/value&gt;
&lt;value key=&quot;gender&quot;&gt;female&lt;/value&gt;
&lt;/map&gt;
&lt;/Config&gt;

You could create your custom marshaller using javax.xm.parsers solutions:

        try {
final File configFile = Paths.get(&quot;C:/Development/file.xml&quot;).toFile();
final DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
final DocumentBuilder dBuilder;
dBuilder = dbFactory.newDocumentBuilder();
final Document doc = dBuilder.parse(configFile);
final NodeList nodeList = doc.getChildNodes();
if (nodeList.getLength() == 0) {
throw new IllegalArgumentException(&quot;Config is empty or incorrect.&quot;);
}
final NodeList elements = nodeList.item(0).getChildNodes();
final Map&lt;String, User&gt; users = new HashMap&lt;&gt;();
for (int i = 0; i &lt; elements.getLength(); i++) {
final Node item = elements.item(i);
if (!&quot;map&quot;.equals(item.getNodeName())) {
continue;
}
final String key = item.getAttributes().getNamedItem(&quot;name&quot;).getNodeValue();
final NodeList childNodes = item.getChildNodes();
String name;
String age;
String gender;
for (int j = 0; j &lt; childNodes.getLength(); j++) {
final Node childItem = childNodes.item(j);
if (!&quot;value&quot;.equals(childItem.getNodeName())) {
continue;
}
final String fieldName = childItem.getAttributes().getNamedItem(&quot;key&quot;).getNodeValue();
final String fieldValue = childItem.getNodeValue();
switch (fieldName) {
case &quot;name&quot;:
name = childItem.getNodeValue();
break;
case &quot;age&quot;:
age = childItem.getNodeValue();
break;
case &quot;gender&quot;:
gender = childItem.getNodeValue();
break;
default:
throw new IllegalArgumentException(String.format(&quot;Unknown user field %s&quot;, fieldName));
}
}
users.put(key, new User(name, age, gender));
}
} catch (final ParserConfigurationException | SAXException | IOException e) {
throw new IllegalArgumentException(&quot;Error during config parsing&quot;);
}

EDIT:
Due to comments under the main post and my inability to write there, I will write here:
Config properties file is a commonly used structure of key-value pairs serialized into file as in following example:

property.name=value
other.property.name=value

XML file is form of data structure as well, although the possibilities for XML files are wider and provide more data flexibility as well as objects serialization. Your configuration can be stored in properties format, XML, JSON, etc. However the type of your data suggests usage of more complex data storage structure than properties

huangapple
  • 本文由 发表于 2020年9月2日 22:48:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/63708065.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定