【问题标题】:Extract XML Information to List<Map> using XPath使用 XPath 将 XML 信息提取到 List<Map>
【发布时间】:2011-11-28 12:57:41
【问题描述】:

我有一个来自 SOAP 响应的 XML 数据,如下例所示:

<EMP>
   <PERSONAL_DATA>
     <EMPLID>AA0001</EMPLID>
     <NAME>Adams<NAME>
   </PERSONAL_DATA>
   <PERSONAL_DATA>
     <EMPLID>AA0002<EMPLID>
     <NAME>Paul<NAME>
    </PERSONAL_DATA>
</EMP>

我想将每个员工的信息存储在Map(KEY,VALUE) KEY=tagname, VALUE=value 并希望在 java 中使用 XPATH 为所有员工创建一个LIST&lt;MAP&gt;。这是怎么做到的?

我尝试了以下方法:

 public static List createListMap(String path, SOAPMessage response,Map map) {
            List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();       
              try {
                 XPath xpath = XPathFactory.newInstance().newXPath();
                 XPathExpression expr = xpath.compile("//" + path + "/*");
                Object re =expr.evaluate(response.getSOAPBody(), XPathConstants.NODESET);
                NodeList nodes = (NodeList)res;                           
                for (int i = 0; i < nodes.getLength(); i++) {
                    if (nodes.item(i).getFirstChild() != null &&
                        nodes.item(i).getFirstChild().getNodeType() == 1) {
                        Map<String, Object> map1 = new HashMap<String, Object>();
                        map.put(nodes.item(i).getLocalName(),  map1);
                        createListMap(nodes.item(i).getNodeName(), response,map1);
                        list.add(map);                
                    }
                    else { 
                      map.put(nodes.item(i).getLocalName(),nodes.item(i).getTextContent());                                                  
                    }
return list;                
}

我调用了类似createListMap("EMP",response,map); 的方法(响应是一个SoapResponse)。 在 XPATH //PERSONAL_DATA/* 中出现问题。在递归中,它列出了两个员工的数据,但我想将每个员工的数据存储在自己的地图中,然后创建这些 MAP 的列表......我该怎么做?

【问题讨论】:

    标签: java xml xpath


    【解决方案1】:

    表达式//PERSONAL_DATA/* 选择每个PERSONAL_DATA 元素的所有子元素,这正是您描述的问题。相反,选择 PERSONAL_DATA 元素本身并迭代它们的子元素。

    例子:

    public NodeList eval(final Document doc, final String pathStr) 
            throws XPathExpressionException  {
        final XPath xpath = XPathFactory.newInstance().newXPath();
        final XPathExpression expr = xpath.compile(pathStr);
        return (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
    }
    
    public List<Map<String, String>> fromNodeList(final NodeList nodes) {
        final List<Map<String, String>> out = new ArrayList<Map<String,String>>(); 
        int len = (nodes != null) ? nodes.getLength() : 0;
        for (int i = 0; i < len; i++) {
            NodeList children = nodes.item(i).getChildNodes();
            Map<String, String> childMap = new HashMap<String, String>();
            for (int j = 0; j < children.getLength(); j++) {
                Node child = children.item(j);
                if (child.getNodeType() == Node.ELEMENT_NODE)
                    childMap.put(child.getNodeName(), child.getTextContent());
            }
            out.add(childMap);
        }
        return out;
    }
    

    这样使用:

    List<Map<String, String>> nodes = fromNodeList(eval(doc, "//PERSONAL_DATA"));
    System.out.println(nodes);
    

    输出:

    [{NAME=Adams, EMPLID=AA0001}, {NAME=Paul, EMPLID=AA0002}]
    

    如果您实际上处理的是更复杂的结构,带有额外的嵌套元素(我怀疑您是这样),那么您需要单独迭代这些层或使用类似 JAXB 的方式对数据进行建模。

    【讨论】:

    • 韦恩,这对我帮助很大。但在这里我想创建“EMPLID”作为键和属性的其余部分作为值....有可能吗?任何提示都会很好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多