从JTree中识别所选XML节点的索引

时间:2016-07-20 13:14:54

标签: java xml

我有一个JTree,输入XML文件映射到它。

library_system.xml

<library>
    <user>
        <name>Dinesh</name>
        <book>
            <info name="java">Java: The Complete Reference, 9th Edition</info>
            <info name="price">700</info>
            <details>
                <parameter name="author">Herbert Schildt</parameter>
                <parameter name="isbn">9339212096</parameter>
                <parameter name="publisher">McGraw Hill Education</parameter>
            </details>
        </book>
        <book>
            <info name="java">Learning Python 3rd Edition</info>
            <info name="price">1020</info>
            <details>
                <parameter name="author">Mark Lutz</parameter>
                <parameter name="isbn">0596513984</parameter>
                <parameter name="publisher">O'Reilly</parameter>
            </details>
        </book>
    </user>
    <user>
        <name>Vignesh</name>
        <book>
            <info name="java">Java: The Complete Reference, 9th Edition</info>
            <info name="price">700</info>
            <details>
                <parameter name="author">Herbert Schildt</parameter>
                <parameter name="isbn">9339212096</parameter>
                <parameter name="publisher">McGraw Hill Education</parameter>
            </details>
        </book>
    </user>
</library>

当从JTree中选择任何XML节点时,我正在打印所选节点名称及其父名称。

StackOverFlow.java

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author dsivaji
 */
public class StackOverFlow {

    public DefaultMutableTreeNode rootNode = null;//For writing
    public Element rootElement = null;
    private DocumentBuilder dBuilder = null;
    public Document doc = null;
    private String xmlFileName = null;
    public static DefaultMutableTreeNode lastNode = null;
    static String selctedXmlProperty = "";
    static String primaryCond = "";
    static Map<String, List> conditionsMap = new HashMap<String, List>();


    public StackOverFlow(String xmlFileName) {

        try {
            dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            doc = dBuilder.newDocument();

            if (rootNode == null) {
                rootElement = doc.createElement("devices");
                doc.appendChild(rootElement);
                rootNode = new DefaultMutableTreeNode(rootElement.getNodeName());
            }
            this.xmlFileName = xmlFileName;
        } catch (Exception e) {
            System.out.println("Exception in the XML document builders at the constructuor of XMLManipulator");
        }
    }

    static DefaultMutableTreeNode parseXML(String xmlFileName) {

        DefaultMutableTreeNode masterRootNode = null;
        DocumentBuilder dBuilder = null;
        Document doc = null;

        try {
            dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            doc = dBuilder.newDocument();
            doc = dBuilder.parse(xmlFileName);
            if (doc.hasChildNodes()) {
                masterRootNode = getXMLTree(doc.getChildNodes(), null);
            }
        } catch (Exception e) {
            System.out.println("Exception in XML parsing" + e);
            System.out.println("ex : " + e);
            masterRootNode = new DefaultMutableTreeNode("ERROR");
        }

        return masterRootNode;
    }

    private static DefaultMutableTreeNode getXMLTree(NodeList nodeList, DefaultMutableTreeNode treeParent) {

        //This will be assumed to be master one.
        DefaultMutableTreeNode rootParent = null;

        //If treeParent is null, then it called from the main, not a recursive one.
        if (treeParent == null) {
            rootParent = new DefaultMutableTreeNode("");
        } else {
            rootParent = treeParent;
        }

        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) {

                // get node name and value
                String myNodeName = tempNode.getNodeName().toUpperCase();

                DefaultMutableTreeNode parent = new DefaultMutableTreeNode(myNodeName);
                lastNode = parent;
//                System.out.println(tempNode.getNodeName() + " : " + tempNode.getNodeValue());
                //If it has the attributes, then appending it with the parent text 
                if (tempNode.hasAttributes()) {

                    // get attributes names and values
                    NamedNodeMap nodeMap = tempNode.getAttributes();

                    for (int i = 0; i < nodeMap.getLength(); i++) {

                        Node node = nodeMap.item(i);
                        String nodeName = node.getNodeName();
                        if (nodeName.equals("name")) {
                            System.out.println("attr value : " + node.getNodeValue() + ", " + tempNode.getNodeValue());

                            parent.setUserObject(myNodeName + " (" + node.getNodeValue() + ")");
                        }
//                        System.out.print("attr name : " + node.getNodeName());

                    }
                } else {
//                    System.out.println("Node Text content = " + tempNode.getTextContent());
                }

                //Adding it to the root parent of this current context
                rootParent.add(parent);

                if (tempNode.hasChildNodes()) {
                    // loop again if has child nodes and add it to the rootParent
                    rootParent.add(getXMLTree(tempNode.getChildNodes(), parent));
                }
//                System.out.println("Node Name = " + tempNode.getNodeName() + " [CLOSE]");
            } else if (tempNode.getNodeType() == Node.TEXT_NODE) {
                String txtVal = tempNode.getNodeValue().trim();
                if (!txtVal.isEmpty()) {
                    if (lastNode != null) {
                        lastNode.setUserObject(lastNode.getUserObject() + " = " + txtVal);
                    }
                    System.out.println("->" + txtVal + "<-");
                }
            }
        }
        return rootParent;
    }

    public void removeChilds(Node node) {
        while (node.hasChildNodes()) {
            node.removeChild(node.getFirstChild());
        }
    }

    public static void main(String[] args) {
        showGUI("C:\\library_system.xml");
    }

    public static void showGUI(final String logXmlFileName) {
        JFrame topoWindow = new JFrame("Library Info");
        topoWindow.setTitle(logXmlFileName.substring(logXmlFileName.lastIndexOf("\\") + 1));
        topoWindow.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

        final JTree topoTree = new JTree(parseXML(logXmlFileName));

        topoTree.addTreeSelectionListener(new TreeSelectionListener() {

            public void valueChanged(TreeSelectionEvent e) {
                JTree treeSource = (JTree) e.getSource();
                TreePath tp = e.getNewLeadSelectionPath();

//                System.out.println(Arrays.toString(e.getPaths()));
                System.out.println(e.getPath());
//                System.out.println(tp.getParentPath() + " at " + tp.getPathCount());
                if (tp != null) {

                    TreeNode lastPathComponent = (TreeNode) tp.getLastPathComponent();
                    System.out.println(lastPathComponent.isLeaf());
                    System.out.println("parent -> " + lastPathComponent.getParent().toString());
                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) tp.getLastPathComponent();
                    System.out.println(node.getParent().getIndex(node));
//                    System.out.println("parent ->" + lastPathComponent.getParent().getParent().getChildCount());
                    selctedXmlProperty = tp.getLastPathComponent().toString();
                    System.out.println("val ->" + tp.getLastPathComponent());
                }
            }
        });
        final JScrollPane scrlTreeView = new JScrollPane(topoTree);

        final JPanel pnlLeft = new JPanel(new BorderLayout(5, 5));

        pnlLeft.add(scrlTreeView);

        topoWindow.add(pnlLeft);

        for (int i = 0; i < topoTree.getRowCount(); i++) {
//                System.out.println(topoTree.getPathForRow(i));
            topoTree.expandRow(i);
        }

        topoWindow.pack();
        topoWindow.setLocationRelativeTo(null);
        topoWindow.setSize(500, 500);
        topoWindow.setVisible(true);
    }
}

输出 enter image description here

[, LIBRARY, USER, BOOK, DETAILS, PARAMETER (author) = Herbert Schildt]
true
parent -> DETAILS
0
val ->PARAMETER (author) = Herbert Schildt

以上消息归因于以下方法

public void valueChanged(TreeSelectionEvent e) {
    JTree treeSource = (JTree) e.getSource();
    TreePath tp = e.getNewLeadSelectionPath();
    System.out.println(e.getPath());
    if (tp != null) {
        TreeNode lastPathComponent = (TreeNode) tp.getLastPathComponent();
        System.out.println(lastPathComponent.isLeaf());
        System.out.println("parent -> " + lastPathComponent.getParent().toString());
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) tp.getLastPathComponent();
        System.out.println(node.getParent().getIndex(node));
        selctedXmlProperty = tp.getLastPathComponent().toString();
        System.out.println("val ->" + tp.getLastPathComponent());
    }
}

在这里,我该怎么做才能知道一个人选择了第二个user元素的第一个book元素的第一个detail元素名为author的元素?

1 个答案:

答案 0 :(得分:1)

valueChanged中添加以下方法调用printDetails

public void valueChanged(TreeSelectionEvent e) {
                JTree treeSource = (JTree) e.getSource();
                printDetails(e.getNewLeadSelectionPath());//This One
                TreePath tp = e.getNewLeadSelectionPath();

方法printDetails将获取当前节点的父节点(当前节点名为me)并尝试在父节点的子节点列表中找到我。一旦发现它打印带有索引的消息,并对父进行相同的操作,直到它到达root。如果您不想使用0-index,请在打印之前将{1}添加到i

private void printDetails(TreePath me) {
                DefaultMutableTreeNode mee = (DefaultMutableTreeNode) me.getLastPathComponent();
                TreePath parent = me.getParentPath();
                if(parent == null){
                    return;
                }
                DefaultMutableTreeNode lastPathComponent = (DefaultMutableTreeNode) (parent.getLastPathComponent());
                for (int i = 0; i < lastPathComponent.getChildCount(); i++) {
                    if (lastPathComponent.getChildAt(i).equals(mee)) {
                        System.out.println(mee.getUserObject() + " I am the " + i + "th child of " + lastPathComponent.getUserObject());
                    }
                }
                printDetails(parent);
            }