2014-10-03 37 views
0

任务:读取XML文件以创建模板;基于密钥中某些字符串的一部分从HashMap中检索密钥?

我正在阅读这个XML文件,如下所述,并将其放入HashMap中。得到一个键值对, 其中Key是元素属性“name”下的值,Value是元素值。 如:关键:map.abc.color.PRIMARY和值:#FFFFFF 如:关键:map.abc.node.TEXT1和值:数值

<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的关键中的最后一个句号之后大写字母(或者可能是任何其他选项)结束

+0

你必须遍历整组键,并检查(用正则表达式或简单地拆分字符串)哪些最后一部分大写。 – 2014-10-03 01:46:19

+0

您正在使用错误的数据结构作业。数据库可以很容易地做到这一点。否则你需要一张辅助地图。 – EJP 2014-10-03 01:47:13

回答

1

可以匹配的关键下面的正则表达式,看看它是否返回true:

key.matches(".*\\.[A-Z]+"); 
+0

只有密钥以大写字母结束,thiw才有效。他的发言说明了关键的任何部分。尽管示例只显示大写结尾 – 75inchpianist 2014-10-03 01:48:03

+0

另一方面,OP的最后一行说明了这一点。我想,当他说最后一个元素时,他意味着他的“分离”字符串的最后一部分。 – 2014-10-03 02:02:26

+0

只是为了清除,如果关键是“map.abc.color。SECONDARY“,那么我需要在最后一段时间后以大写字母结尾的密钥。我正在使用以下模式来检索它,并且正在工作:key.matches(”map.abc。*。* \\ p {Lu} $“ )或可能是key.matches(“map。*。* \\ p {Lu} $”) – Cozmonaut 2014-10-04 00:43:49

1

OK,现在我们有更多的细节,我们可以解决你的数据结构。在我看来,你在这里有一个分层的地图。您的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 } 
    } 
    } 
} 
0

它在我看来,你正试图从一个Java属性风格的值列表转换为JavaScript对象。

以下是一种可能性:您可以将属性样式Map“unflatten”为递归的maps/values映射,然后利用其中一个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(); 
    } 
    } 

另外,它不应该太难写自己的打印程序的地图数据结构的地图。