使用DOM解析器从XML文档中创建JTree

时间:2022-06-30 12:38:01
package xml;

import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;

import java.io.*;

public class ThirdParser extends JFrame{
    DocumentBuilderFactory factory;
    DocumentBuilder builder;
    File f;
    Document d;
    JTree tree;
    JScrollPane scroll;
//------------------------------------------------------------------------------
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override public void run(){
                new ThirdParser();
            }
        });
    }
//------------------------------------------------------------------------------
    public ThirdParser(){
        try{

            factory = DocumentBuilderFactory.newInstance();
            builder = factory.newDocumentBuilder();
            f = new File("E:/Website Projects/XML/helloWorld.xml");
            d = builder.parse(f);
            String people = "people";
            DefaultMutableTreeNode node = new DefaultMutableTreeNode(people);
            tree = new JTree(node);
            Element e = d.getDocumentElement();

            if(e.hasChildNodes()){
                DefaultMutableTreeNode root = new DefaultMutableTreeNode
                                                            (e.getTagName());
                NodeList children = e.getChildNodes();
                for(int i=0;i<children.getLength();i++){
                    Node child = children.item(i);
                    visit(child,root);
                }
            }
        }catch(ParserConfigurationException e){
            e.printStackTrace();
        }catch(SAXException e){
            e.printStackTrace();
        }catch(IOException e){
            e.printStackTrace();
        }
//      scroll = new JScrollPane(tree);

        this.add(tree);
        this.setVisible(true);
        this.pack();
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);

    }
//------------------------------------------------------------------------------
    public void visit(Node child,DefaultMutableTreeNode parent){
        short type = child.getNodeType();
        if(type == Node.ELEMENT_NODE){
            Element e = (Element)child;
            DefaultMutableTreeNode node = new DefaultMutableTreeNode
                                        (e.getTagName());
            parent.add(node);

            if(e.hasChildNodes()){
                NodeList list = e.getChildNodes();
                for(int i=0;i<list.getLength();i++){
                    visit(list.item(i),node);
                }
            }

        }else if(type == Node.TEXT_NODE){
            Text t = (Text)child;
            String textContent = t.getTextContent();
            DefaultMutableTreeNode node = new DefaultMutableTreeNode(
                    textContent);
            parent.add(node);
        }
    }
//------------------------------------------------------------------------------
}  

This is my code to parse an XML document and represent it as a JTree. The problem is that I only get the root node in the JTree and nothing else. I tried walking the directory structure with a code similar to this and that worked. I do not know why this does not give me the result I expect.

这是我解析XML文档并将其表示为JTree的代码。问题是,我只获得了JTree中的根节点,其他的都没有。我尝试使用类似于这个和那个的代码来遍历目录结构。我不知道为什么这不能给我我所期望的结果。

Image

使用DOM解析器从XML文档中创建JTree

XML

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE people SYSTEM "validator.dtd">

<people>
    <student>
        <name>John</name>
        <course>Computer Technology</course>
        <semester>6</semester>
        <scheme>E</scheme>
    </student>

    <student>
        <name>Foo</name>
        <course>Industrial Electronics</course>
        <semester>6</semester>
        <scheme>E</scheme>
    </student>
</people>

Note: If I enter System.out.println() in the visit() method to print element and text nodes, it prints fine. Just that nodes are not added.

注意:如果我在visit()方法中输入System.out.println()来打印元素和文本节点,那么它会打印得很好。只是没有添加节点。

2 个解决方案

#1


4  

Looks like you are adding the children to the wrong parent node. The tree root is set tree = new JTree(node);, but then you add children to DefaultMutableTreeNode root = new DefaultMutableTreeNode(e.getTagName()); which is not part of the tree at all. Quick fix would be changing:

看起来您将子节点添加到错误的父节点。树根是set tree = new JTree(节点);然后将子节点添加到DefaultMutableTreeNode根= new DefaultMutableTreeNode(e.getTagName());这不是树的一部分。快速修复将会改变:

visit(child,root);

to

visit(child,node);

Or execute node.add(root); once all nodes were visited.

或执行node.add(根);一旦访问了所有节点。

#2


1  

Try this and it should work:

试试这个,它应该是有用的:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.tree.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.*;
import org.xml.sax.SAXException;


/**
 * XmlJTree class
 * @author Ibrabel
 */
public final class XmlJTree extends JTree{

    DefaultTreeModel dtModel=null;

    /**
     * XmlJTree constructor
     * @param filePath
     */
    public XmlJTree(String filePath){
        if(filePath!=null)
        setPath(filePath);
    }

    public void setPath(String filePath){
        Node root = null;
        /*
            Parse the xml file
        */
        try {
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(filePath);
            root = (Node) doc.getDocumentElement();
        } catch (IOException | ParserConfigurationException | SAXException ex) {
            JOptionPane.showMessageDialog(null,"Can't parse file",
                            "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        /*
            if any result set the appropriate model to the jTree
        */
        if(root!=null){
            dtModel= new DefaultTreeModel(builtTreeNode(root));
            this.setModel(dtModel);
        }
    }

    /**
     * fullTreeNode Method
     * construct the full jTree from any xml file
     * this method is recursive
     * @param root
     * @return DefaultMutableTreeNode
     */
    private DefaultMutableTreeNode builtTreeNode(Node root){
        DefaultMutableTreeNode dmtNode;

        dmtNode = new DefaultMutableTreeNode(root.getNodeName());
            NodeList nodeList = root.getChildNodes();
            for (int count = 0; count < nodeList.getLength(); count++) {
                Node tempNode = nodeList.item(count);
                // make sure it's element node.
                if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
                    if (tempNode.hasChildNodes()) {
                        // loop again if has child nodes
                        dmtNode.add(builtTreeNode(tempNode));
                    }
                }
            }
        return dmtNode;
    }

    public static void main(String[] args) {
        /*
            Create simple frame for the example
        */
        JFrame myFrame = new JFrame();
        myFrame.setTitle("XmlJTreeExample");
        myFrame.setSize(300, 500);
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setLocationRelativeTo(null);
        JPanel pan = new JPanel(new GridLayout(1, 1));
        /*
            Add jTree
        */
        final XmlJTree myTree = new XmlJTree(null);
        myFrame.add(new JScrollPane(myTree));
        /*
            Add a button to choose the file
        */
        JButton button = new JButton("Choose file");
        button.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent ae) {
                JFileChooser chooser = new JFileChooser();
                FileNameExtensionFilter filter = new FileNameExtensionFilter(
                        "XML file", "xml");
                chooser.setFileFilter(filter);
                int returnVal = chooser.showOpenDialog(null);
                if(returnVal == JFileChooser.APPROVE_OPTION) {
                    myTree.setPath(chooser.getSelectedFile().getAbsolutePath());
                }
            }
        });
        pan.add(button);
        /*
            Add the JPanel to the JFrame and set the JFrame visible
        */
        myFrame.add(pan,BorderLayout.SOUTH);
        myFrame.setVisible(true);
    }
}

#1


4  

Looks like you are adding the children to the wrong parent node. The tree root is set tree = new JTree(node);, but then you add children to DefaultMutableTreeNode root = new DefaultMutableTreeNode(e.getTagName()); which is not part of the tree at all. Quick fix would be changing:

看起来您将子节点添加到错误的父节点。树根是set tree = new JTree(节点);然后将子节点添加到DefaultMutableTreeNode根= new DefaultMutableTreeNode(e.getTagName());这不是树的一部分。快速修复将会改变:

visit(child,root);

to

visit(child,node);

Or execute node.add(root); once all nodes were visited.

或执行node.add(根);一旦访问了所有节点。

#2


1  

Try this and it should work:

试试这个,它应该是有用的:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.tree.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.*;
import org.xml.sax.SAXException;


/**
 * XmlJTree class
 * @author Ibrabel
 */
public final class XmlJTree extends JTree{

    DefaultTreeModel dtModel=null;

    /**
     * XmlJTree constructor
     * @param filePath
     */
    public XmlJTree(String filePath){
        if(filePath!=null)
        setPath(filePath);
    }

    public void setPath(String filePath){
        Node root = null;
        /*
            Parse the xml file
        */
        try {
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(filePath);
            root = (Node) doc.getDocumentElement();
        } catch (IOException | ParserConfigurationException | SAXException ex) {
            JOptionPane.showMessageDialog(null,"Can't parse file",
                            "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        /*
            if any result set the appropriate model to the jTree
        */
        if(root!=null){
            dtModel= new DefaultTreeModel(builtTreeNode(root));
            this.setModel(dtModel);
        }
    }

    /**
     * fullTreeNode Method
     * construct the full jTree from any xml file
     * this method is recursive
     * @param root
     * @return DefaultMutableTreeNode
     */
    private DefaultMutableTreeNode builtTreeNode(Node root){
        DefaultMutableTreeNode dmtNode;

        dmtNode = new DefaultMutableTreeNode(root.getNodeName());
            NodeList nodeList = root.getChildNodes();
            for (int count = 0; count < nodeList.getLength(); count++) {
                Node tempNode = nodeList.item(count);
                // make sure it's element node.
                if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
                    if (tempNode.hasChildNodes()) {
                        // loop again if has child nodes
                        dmtNode.add(builtTreeNode(tempNode));
                    }
                }
            }
        return dmtNode;
    }

    public static void main(String[] args) {
        /*
            Create simple frame for the example
        */
        JFrame myFrame = new JFrame();
        myFrame.setTitle("XmlJTreeExample");
        myFrame.setSize(300, 500);
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setLocationRelativeTo(null);
        JPanel pan = new JPanel(new GridLayout(1, 1));
        /*
            Add jTree
        */
        final XmlJTree myTree = new XmlJTree(null);
        myFrame.add(new JScrollPane(myTree));
        /*
            Add a button to choose the file
        */
        JButton button = new JButton("Choose file");
        button.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent ae) {
                JFileChooser chooser = new JFileChooser();
                FileNameExtensionFilter filter = new FileNameExtensionFilter(
                        "XML file", "xml");
                chooser.setFileFilter(filter);
                int returnVal = chooser.showOpenDialog(null);
                if(returnVal == JFileChooser.APPROVE_OPTION) {
                    myTree.setPath(chooser.getSelectedFile().getAbsolutePath());
                }
            }
        });
        pan.add(button);
        /*
            Add the JPanel to the JFrame and set the JFrame visible
        */
        myFrame.add(pan,BorderLayout.SOUTH);
        myFrame.setVisible(true);
    }
}