2010-08-30 104 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)); 
    } 
} 

基本上就意味着文檔中的每個節點將被訪問。