代码之家  ›  专栏  ›  技术社区  ›  Crystal

用Java解析XML文件

  •  1
  • Crystal  · 技术社区  · 15 年前

    在下面的示例代码中,我有一个关于列表的问题。My prof将文档对象添加到ArrayList。这似乎只是将一个文档对象添加到列表中,而不是每个节点。但是在while循环中,他似乎得到了索引0处的项,解析了信息,然后删除了该项,以便查看下一个信息。因此,ArrayList中的内容似乎比单文档对象中的内容更多。在ArrayList/while循环部分发生了什么?我对这个代码的工作原理感到困惑。提前谢谢!

    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 回复  |  直到 15 年前
        1
  •  2
  •   Jacob Tomaw    15 年前

    我认为你们的教授在这里演示的叫做广度优先算法。循环中的关键代码块是

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

    我使用这个算法,首先处理根元素,然后是它的子元素,然后是它们的子元素,然后是下面的子元素,依此类推,直到树中只有叶子。

    (另一方面:对于一般的XML文档和RSS提要来说,这似乎是错误的方法。我想你应该做深度优先算法,使输出更容易理解。在这种情况下,可以使用堆栈而不是列表。)

        2
  •  1
  •   mwittrock    15 年前

    每个节点的每个子节点都被添加到 List<Node> 按此代码:

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

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