如何动态返回每个节点的一组对象?

时间:2014-06-12 02:50:48

标签: java dom domparser

亲爱的所有有价值的会员!!

使用DOM技术读取xml时遇到了一些问题。我想获得每个xml节点/元素的一组对象。一组对象应包含如下:MyObject(String NodeName,String NodeValue,Map attributeMap)。有可能用DOM做到这一点吗?任何建议表示赞赏。这是我的例子:

1 / xml文件:

<?xml version="1.0"?>
<company>
    <staff id="1001" adress="new york">
        <firstname>yong</firstname>
        <lastname>mook kim</lastname>
        <nickname>mkyong</nickname>
        <salary>100000</salary>
    </staff>
</company>

2 /预期的回报结果:

First set: 
   NodeName  = company
   NodeValue = null
   attributeMap = {null}
Second set: 
   NodeName  = staff
   NodeValue = null
   attributeMap = {id="1001",address="new york"}
Third Set:
   NodeName  = firstname
   NodeValue = yong
   attributeMap = {null}
Forth Set: 
   NodeName  = lastName
   NodeValue = mook kim
   attributeMap = {null}
And so on...

以下是我的示例代码*

public ElementsContainer getElements(String filename) throws 
        ParserConfigurationException, SAXException, IOException{

    Node tempNode;
    NamedNodeMap nodeMapAttributes;
    Node node;
    Map<String, String> attributes = new HashMap<>();
    ElementsContainer elements = null;


    File file = new File(filename);
    DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document document = documentBuilder.parse(file);
    if(document.hasChildNodes()){
        for(int i=0; i<document.getChildNodes().getLength(); i++){
            tempNode = document.getChildNodes().item(i);
            if(tempNode.getNodeType() == Node.ELEMENT_NODE){
                if(tempNode.getNodeValue()==null){
                   if(tempNode.hasAttributes()){
                       nodeMapAttributes = tempNode.getAttributes();
                       for(int k=0; k<nodeMapAttributes.getLength(); k++){
                           node = nodeMapAttributes.item(k);
                           attributes.put(node.getNodeName(), node.getNodeValue());
                       }
                   }
                   else{
                       attributes.put("", "");
                   }
                   elements = new ElementsContainer(tempNode.getNodeName(),tempNode.getNodeValue(),attributes);
                }
                else{
                    if(tempNode.hasAttributes()){
                       nodeMapAttributes = tempNode.getAttributes();
                       for(int k=0; k<nodeMapAttributes.getLength(); k++){
                           node = nodeMapAttributes.item(k);
                           attributes.put(node.getNodeName(), node.getNodeValue());
                       }
                   }
                   else{
                       attributes.put("", "");
                   }
                   elements = new ElementsContainer(tempNode.getNodeName(),tempNode.getNodeValue(),attributes);
                }
            }
        }
    }
    return elements;
}

1 个答案:

答案 0 :(得分:2)

我很好奇为什么没有使用我在your similar question中提供的类似方法。

然而,您必须在当前的方法中解决这两个问题

  • 节点是嵌套的,单次通过是不够的
  • 捕获某种Collection中的每个Node
  • 作为解决的第三个兴趣点,尽可能多地摆脱if-else

一旦接近递归遍历Document

private void processNodes(final NodeList list, 
                          final ElementContainer parent, 
                          final List<ElementContainer> elements){

  for(int i=0; i< list.getLength(); i++){
      final Node node = list.item(i);
       if("#text".equals(node.getNodeName())){
         parent.setValue(node.getNodeValue());
       }
       else{
         final ElementContainer p =  processNode(node, elements);
         processNodes(node.getChildNodes(), p, elements);
       }
  }
}

捕获每个节点:

private ElementContainer processNode(Node node, List<ElementContainer> elements){
  final ElementContainer element = new ElementContainer(node.getNodeName(), node.getNodeValue());

 if(node.hasAttributes()){
   final NamedNodeMap attrs = node.getAttributes();
   for(int k=0; k<attrs.getLength(); k++){
     final Node attr = attrs.item(k);
     element.addAttribute(attr.getNodeName(), attr.getNodeValue());
   }
  }
  elements.add(element);
  return element;
}

查看my example