2010-08-30 61 views
1

在下面的示例代码中,我对List有个疑问。我的教授将Document对象添加到ArrayList。看起来这只是将一个Document对象添加到列表中,而不是每个单独的Node。但是看着while循环,似乎他得到索引0处的项目,解析信息,然后删除该项目,以便他可以查看下一个信息。所以看起来好像还有更多的事情发生在ArrayList中,然后就是一个Document对象。是否在ArrayList/while循环部分发生了什么?我对这个代码的工作原理感到困惑。提前致谢!解析Java中的XML文件

import java.io.*; 
import java.util.*; 
import javax.xml.parsers.*; 
import org.w3c.dom.*; 
import org.xml.sax.*; 


public class RSSReader { 
    public static void main(String[] args) { 
     File f = new File("testrss.xml"); 
     if (f.isFile()) { 
      System.out.println("is File"); 
      RSSReader xml = new RSSReader(f); 
     } 
    } 

    public RSSReader(File xmlFile) { 
     try { 
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder builder = factory.newDocumentBuilder(); 
      Document doc = builder.parse(xmlFile); 

      List<Node> nodeList = new ArrayList<Node>(); 
      nodeList.add(doc); 

      while(nodeList.size() > 0) 
      { 
      Node node = nodeList.get(0); 

      if (node instanceof Element) { 
       System.out.println("Element Node: " + ((Element)node).getTagName()); 
       NamedNodeMap attrMap = node.getAttributes(); 
       for(int i = 0; i < attrMap.getLength(); i++) 
       { 
        Attr attribute = (Attr) attrMap.item(i); 
        System.out.print("\tAttribute Key: " + attribute.getName() 
         + " Value: " + attribute.getValue()); 
       } 
       if(node.hasAttributes()) 
        System.out.println(); 
      } 
      else if(node instanceof Text) 
       System.out.println("Text Node: " + node.getNodeValue()); 
      else 
       System.out.println("Other Type: " + node.getNodeValue()); 

      if(node.hasChildNodes()) 
      { 
       NodeList nl = node.getChildNodes(); 
       for(int i = 0; i < nl.getLength(); i++) 
       { 
        nodeList.add(nl.item(i)); 
       } 
      } 
      nodeList.remove(0); 
      } 
     } 

     catch (IOException e) { 
      e.printStackTrace(); 
     } 
     catch (SAXException e) { 
      e.printStackTrace(); 
     } 
     catch (IllegalArgumentException e) { 
      e.printStackTrace(); 
     } 
     catch (ParserConfigurationException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

回答

2

我认为你的教授在这里展示的称为宽度优先算法。在循环代码密钥块是

if(node.hasChildNodes()) 
{ 
    NodeList nl = node.getChildNodes(); 
    for(int i = 0; i < nl.getLength(); i++) 
    { 
     nodeList.add(nl.item(i)); 
    } 
} 

处理列表中的一个元素后,如果元件具有要处理的子元素此代码将CHACK。如果是这样,这些将被添加到列表中进行处理。

我使用这种算法,首先处理根元素,然后是它的子元素,然后是他们的子元素,然后是下面的子元素,依此类推,直到树中只有叶子。 (注意:这似乎是对一般XML文档和RSS提要的错误处理方式,我想你应该使用深度优先算法来使输出更容易理解,在那篇文章中,例如,您可以使用堆栈而不是列表。)

1

每个节点的每个孩子都被这个代码添加到List<Node>

if(node.hasChildNodes()) 
{ 
    NodeList nl = node.getChildNodes(); 
    for(int i = 0; i < nl.getLength(); i++) 
    { 
     nodeList.add(nl.item(i)); 
    } 
} 

基本上就意味着文档中的每个节点将被访问。