任务:读取XML文件以创建模板;
我正在阅读下面提到的这个XML文件并将其放在HashMap中。获得一个键值对, 其中Key是Element属性下的值" name"和价值是元素价值。 例如:Key:map.abc.color.PRIMARY和Value:#FFFFFF 例如:Key:map.abc.node.TEXT1和Value:value1
<properties>
<property name="map.abc.color.PRIMARY">#FFFFFF</property>
<property name="map.abc.color.SECONDARY">#F0F0F0</property>
<property name="map.abc.node.TEXT1">value1</property>
<property name="map.abc.node.TEXT2">value2</property>
<property name="map.abc.node.lowercase">value3</property>
<property name="map.abc.strFile">/path/to/file</property>
<property name="map.pqr.color.PRIMARY">#000000</property>
<property name="map.pqr.color.SECONDARY">#ABABAB</property>
<property name="map.pqr.node.WORD1">value4</property>
<property name="map.pqr.node.WORD2">value5</property>
<property name="map.abc.node.lowercase">value6</property>
<property name="map.pqr.strFile">/path/to/file</property>
</properties>
以下是要写入文件的模板(使用StringBuffer)输出。
abc = {
color: {PRIMARY_COLOR:"#FFFFFF",SECONDARY_COLOR:"#F0F0F0"}
node:{TEXT1:"value1",TEXT2:"value2"}
};
pqr = {
color: {PRIMARY_COLOR:"#FFFFFF",SECONDARY_COLOR:"#F0F0F0"}
node:{WORD1:"value4",WORD2:"value5"}
};
Offnote:我正在使用以下模式,该工作正常。
key.matches("map.abc.*.*\\p{Lu}$") or key.matches("map.*.*\\p{Lu}$")
因此,我希望找到一种方法,让所有键在HashMap的Key中的最后一个句点之后以大写字母结尾(或者可能是任何其他选项)
答案 0 :(得分:1)
您可以将密钥与以下正则表达式匹配,并查看它是否返回true:
key.matches(".*\\.[A-Z]+");
答案 1 :(得分:1)
好的,既然我们有更多细节,我们就可以解决您的数据结构问题。在我看来,你在这里有一个分层图。您的name
似乎定义了层次结构。我会使用地图图来存储它:
Map<String, Map<String, Map<String, String>>> structure = new HashMap<>();
解析并填充地图(完全只是伪代码):
path = name.split(".")
// ignore path[0] since it's just 'map'
structure.get(path[1]).get(path[2]).put(path[3], value)
并检索值
for (Map<String, Map<String, String>> element : structure){
for(Map<String, String> group : element) {
for(String attribute : group.keys){
if(allUpper(attribute)) { //DO YOUR THING HERE }
}
}
}
答案 2 :(得分:0)
在我看来,您正在尝试将java属性样式的值列表转换为javascript对象。
这是一种可能性:您可以将属性样式Map
“展开”为映射/值的递归映射,然后利用其中一个JSON库来输出值。以下是一些解决问题的代码:
public class Foo {
private static final String ROOT_NAME = "map";
private static boolean noLowercase(CharSequence s) {
return !s.chars().anyMatch(Character::isLowerCase);
}
private static Map<String, Object> getNextMap(Map<String, Object> map, String mapName) {
Object nextObj = map.get(mapName);
if (nextObj == null) {
nextObj = new LinkedHashMap<String, Object>();
map.put(mapName, nextObj);
}
@SuppressWarnings("unchecked")
Map<String, Object> nextMap = (Map<String, Object>)nextObj;
return nextMap;
}
public static Map<String, Object> unflatten(Map<String, String> properties) {
List<String> sortedKeys = new ArrayList<>(properties.keySet());
Collections.sort(sortedKeys);
Map<String, Object> rootObject = new LinkedHashMap<>();
for (String key : sortedKeys) {
String[] splitKey = key.split("\\.");
String lastItem = splitKey[splitKey.length - 1];
if (noLowercase(lastItem)) {
Map<String, Object> currentMap = rootObject;
for (int i = 1; i < splitKey.length - 1; ++i) {
currentMap = getNextMap(currentMap, splitKey[i]);
}
currentMap.put(lastItem, properties.get(key));
}
}
return rootObject;
}
}
在此之后,使用Gson或Jackson进行序列化应该非常简单。以下是使用Gson的示例:
public static void printMap(Map<String, String> map) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
for (Map.Entry<String, Object> entry : unflatten(map).entrySet()) {
System.out.format("%s = ", entry.getKey());
System.out.print(gson.toJson(entry.getValue()));
System.out.println(";");
System.out.println();
}
}
或者,为地图数据结构地图编写自己的打印例程应该不会太难。