Võ Văn Hải's blog

Chỉ có một điều tuyệt đối đó là mọi thứ đều tương đối…

Dùng DOM đọc file XML biểu biễn trên JTree

Chương trình java sau đây ứng dụng mô hình DOM để duyệt qua 1 văn bản XML sau đó hiển thị lên JTree.

package dom.swing;

import java.awt.BorderLayout;

import java.awt.Dimension;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.ArrayList;

import javax.swing.JFileChooser;

import javax.swing.JFrame;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

import javax.swing.JMenuItem;

import javax.swing.JScrollPane;

import javax.swing.JSplitPane;

import javax.swing.JTextArea;

import javax.swing.JTree;

import javax.swing.event.TreeSelectionEvent;

import javax.swing.event.TreeSelectionListener;

import javax.swing.tree.DefaultMutableTreeNode;

import javax.swing.tree.DefaultTreeModel;

import org.apache.xerces.parsers.DOMParser;

import org.w3c.dom.Attr;

import org.w3c.dom.Document;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

public class ParseTree extends JFrame implements TreeSelectionListener, ActionListener{

private static final long serialVersionUID = 1L;

private DefaultMutableTreeNode root;

private DefaultTreeModel model;

private JTree tree;

private JTextArea taContent;

private JMenuBar menubar;

private JMenu menuFile;

private JMenuItem itemOpen,itemExit;

public ParseTree(){

super(“Parser Tree”);

setDefaultCloseOperation(EXIT_ON_CLOSE);

setSize(700,500);

menubar=new JMenuBar();

menuFile=new JMenu(“File”);

itemOpen=new JMenuItem(“Open”);itemExit=new JMenuItem(“Exit”);

this.setJMenuBar(menubar);

menubar.add(menuFile);

menuFile.add(itemOpen);menuFile.addSeparator();

menuFile.add(itemExit);

itemOpen.addActionListener(this);

itemExit.addActionListener(this);

root=new DefaultMutableTreeNode(“XML Document”);

model=new DefaultTreeModel(root);

tree=new JTree(model);

tree.addTreeSelectionListener(this);

taContent=new JTextArea();

taContent.setEditable(false);

JScrollPane xxx=new JScrollPane(taContent);

JScrollPane sp=new JScrollPane(tree);

sp.setPreferredSize(new Dimension(300,300));

JSplitPane spl=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,sp,xxx);

this.add(spl,BorderLayout.CENTER);

}

void buildtree(String uri){

try {

DOMParser parser=new DOMParser();

parser.parse(uri);

Document doc=parser.getDocument();

addNode(doc,root);

} catch (Exception e) {

e.printStackTrace();

}

}

void addNode(Node xmlNode,DefaultMutableTreeNode treeNode){

if(xmlNode==null)

return;

int type=xmlNode.getNodeType();

MyNode mn=null;

switch (type) {

case Node.DOCUMENT_NODE:{

mn=new MyNode(“xml”,“<?xml version=\”1.0\” encoding =\”UTF-8\”?>”,null);

DefaultMutableTreeNode tn=new DefaultMutableTreeNode(mn);

root.add(tn);

addNode(((Document)xmlNode).getDocumentElement(), treeNode);

break;

}

case Node.ELEMENT_NODE:{

mn=new MyNode(xmlNode.getNodeName(),xmlNode.getNodeValue(),null);

int length=(xmlNode.getAttributes()!=null)?xmlNode.getAttributes().getLength():0;

ArrayList<String>al=new ArrayList<String>();

Attr []attributes=new Attr[length];

for (int i = 0; i < length; i++) {

attributes[i]=(Attr)xmlNode.getAttributes().item(i);

}

String text=“”;

for (int i = 0; i < attributes.length; i++) {

Attr attribute=attributes[i];

text=attribute.getNodeName()+“@”+

attribute.getNodeValue();

al.add(text);//dưa vào danh sách các thuộc tính

}

mn.setAttributes(al);//cap nhật

DefaultMutableTreeNode tn=new DefaultMutableTreeNode(mn);

treeNode.add(tn);

NodeList childNodes=xmlNode.getChildNodes();

if(childNodes!=null){

length=childNodes.getLength();

for (int i = 0; i < length; i++) {

addNode(childNodes.item(i), tn);

}

}

break;

}

case Node.CDATA_SECTION_NODE:{

String x=“<![CDATA[“+

xmlNode.getNodeValue()+

“]]>”;

mn.setNodeValue(x);

break;

}

case Node.TEXT_NODE:{

String newText=xmlNode.getNodeValue().trim();

((MyNode)treeNode.getUserObject()).setNodeValue(newText);

break;

}

case Node.PROCESSING_INSTRUCTION_NODE:{

String text=xmlNode.getNodeValue();

((MyNode)treeNode.getUserObject()).setNodeValue(text);

break;

}

}

}

/**

* @param args

*/

public static void main(String[] args) {

new ParseTree().setVisible(true);

}

@Override

public void valueChanged(TreeSelectionEvent e) {

try {

DefaultMutableTreeNode selNode=(DefaultMutableTreeNode)e.getPath().getLastPathComponent();

Object obj=selNode.getUserObject();

if (obj instanceof MyNode) {

MyNode node=(MyNode)obj;

String text=node.getNodeID()+“:”+node.getNodeValue();

if(node.getAttributes()!=null&&node.getAttributes().size()>0)

text+=“\n”+node.getAttributes().toString();

taContent.setText(text);

}

else

taContent.setText(obj.toString());

} catch (Exception e1) {

e1.printStackTrace();

}

}

@Override

public void actionPerformed(ActionEvent e) {

Object o=e.getSource();

if(o.equals(itemOpen)){

JFileChooser fc=new JFileChooser();

if(fc.showOpenDialog(null)==JFileChooser.APPROVE_OPTION){

String uri=fc.getSelectedFile().getAbsolutePath();

buildtree(uri);

tree.expandRow(0);

}

}

else if(o.equals(itemExit)){

System.exit(1);

}

}

}

Trong đó lớp MyNode.java có nội dung sau

package dom.swing;

import java.util.ArrayList;

public class MyNode {

private String nodeID;//ID

private String nodeValue;//giá trị vủa node

private ArrayList<String>attributes;//lưu giữ các thuộc tính của node

public String getNodeID() {

return nodeID;

}

public void setNodeID(String nodeID) {

this.nodeID = nodeID;

}

public String getNodeValue() {

return nodeValue;

}

public void setNodeValue(String nodeValue) {

this.nodeValue = nodeValue;

}

public ArrayList<String> getAttributes() {

return attributes;

}

public void setAttributes(ArrayList<String> attributes) {

this.attributes = attributes;

}

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = prime * result + ((nodeID == null) ? 0 : nodeID.hashCode());

return result;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

final MyNode other = (MyNode) obj;

if (nodeID == null) {

if (other.nodeID != null)

return false;

} else if (!nodeID.equals(other.nodeID))

return false;

return true;

}

public MyNode(String nodeID, String nodeValue, ArrayList<String> attributes) {

super();

this.nodeID = nodeID;

this.nodeValue = nodeValue;

this.attributes = attributes;

}

public MyNode() {

super();

}

@Override

public String toString() {

return this.nodeID;

}

}

Kết quả thu được như hình sau

DOM

15 Responses to “Dùng DOM đọc file XML biểu biễn trên JTree”

  1. hopvq said

    giúp em với em đang cần cái này nhưng sao em chauyj nó toàn lỗi thui chua chạy được giúp em với có cần phai co file xml ko ạ sao nó toàn lỗi không ai sửa dùm em với.

  2. vovanhai said

    Em đảm bảo là phải có thư viện cho org.apache.xerces.parsers.DOMParser chưa? Nếu chưa, phải download nó về tại trang web của Apache: http://apache.org/. Chúc vui!

  3. lee said

    Thưa thầy, em có viết chương trình java sử dụng các thư viện java bên ngoài của các tổ chức khác(như: apache,w3c để theo tác với các loại dữ liệu: .pdf, .xsl, xml…) thì làm thế nào để thiết lập các thư viện đó mà import nó vào trong chương trình của mình được hả thầy

  4. vovanhai said

    trong java, chỉ cần em chép thư viện (*.jar) theo chương trình của em là OK.

  5. Hung Trung Doan said

    Chao thay Hai,
    em cung rat thich ung dung nay, doc file XML va hien thi len JTREE,
    thay cho em hoi them, neu em muon them icon vao tung Node voi nhung hinh khac nhau, thi em lam sao ha thay

  6. Võ Văn Hải said

    Nè bạn: http://download.oracle.com/javase/tutorial/uiswing/components/tree.html

  7. Võ Công Danh said

    Chào thầy Hải, em rât thích demo này của Thầy!
    – Cho em hỏi, em muốn viết một ứng dụng như thế này mà dùng SAX, thì có khác biệt gì nhiều ko.
    – Và em thêm một số chức năng và yêu cầu như:
    + Sử dụng SAX để tạo menu cho Application từ file XML.
    + Hiện thị nội dung file XML được mở.
    + Chỉnh sữa nội dung file XML (Thêm sữa xóa)

  8. Võ Văn Hải said

    -Viết 1 ứng dụng như vầy dùng SAX cũng được nhưng sẽ rất vất vả bởi DOM bản chất là biểu diễn theo dạng tree, còn SAX duyệt qua 1 lần các element.

    + “Sử dụng SAX để tạo menu cho Application từ file XML”: Duyệt qua các element trong file XML, trong character callback method đọc giá trị của element rồi làm menu.
    +”Hiện nội dung file XML”:

    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.SAXParseException;
    import org.xml.sax.helpers.DefaultHandler;
    import com.sun.org.apache.xerces.internal.parsers.SAXParser;
    public class MyHandler extends DefaultHandler{
    	@Override
    	public void startDocument() throws SAXException {
    		System.out.println("<?xml version = \"1.0\"?>");
    	}
    	@Override
    	public void endDocument() throws SAXException {
    		System.out.println("End document");
    	}
    	
    	@Override
    	public void startElement(String uri, String localName, 
    			String qName,Attributes attributes) 
    	throws SAXException {
    		String atts="";
    		for (int i = 0; i < attributes.getLength(); i++) {
    			atts+=attributes.getQName(i)+"=\""
    				+attributes.getValue(i)+"\" ";
    		}
    		System.out.println("<"+qName+" "+atts+ ">");
    	}
    	
    	@Override
    	public void endElement(String uri, String localName,
    			String qName)throws SAXException {
    		System.out.println("</"+qName+">");
    	}
    	@Override
    	public void characters(char[] ch, int start, 
    			int length)throws SAXException {
    		String st=new String(ch,start,length).trim();
    		System.out.println(st);
    	}
    
            public static void main(String[] args) {
    		try {
    			MyHandler hdl=new MyHandler();
    			SAXParser parser=new SAXParser();
    			parser.setContentHandler(hdl);
    			parser.parse("xmlfiles/yourxmlfile.xml");
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    

    +”Chỉnh sữa nội dung file XML (Thêm sửa xóa)”: SAX không hỗ trợ các thao tác này. SAX chỉ read-only. Muốn có các thao tác CRUD thì dùng DOM.

  9. Huỳnh Thị Dịu said

    Em chào thầy Hải!
    – Em cũng muốn thử viết theo SAX xem như thế nào, rồi so sánh với cách dùm DOM!Nên em đã làm một bài tập của em trên SAX và DOM. Nhưng em mới tìm hiểu java nên con nhiều khó khăn, đặc biệt đối với SAX, em xin thầy hướng dẫn em làm 1 bài tập như bên dưới để em hiểu kỉ về SAX và DOM.
    _ Yêu cầu cụ thể em muốn thể hiện là:(Java application)
    + Sử dụng SAX tạo menu cho ứng dụng từ file XML
    File XML phải quy định được 2 level menu; trong đó:
    + Open : chọn mở file XML
    + Exit: thoát khỏi ứng dụng
    + Save: lưu file XML đã mở và chỉnh sửa
    + Các menu item khác khi click vào thì popup message box “To be implemented.”
    + Hiển thị nội dung file XML được mở:
    + Cấu trúc file dạng cây: tên thẻ; đóng/mở thành phần cây
    + Nội dung mỗi thẻ XML chọn trên cây cấu trúc: thuộc tính và nội dung thẻ.
    (Lưu ý control_textboxes động)
    (Ứng dụng có hai khung thể hiện file XML, tương tự Windows Explorer)
    + Chỉnh sửa nội dung file XML:
    + Xóa thẻ
    + Chỉnh sửa nội dung không có cấu trúc của thẻ XML
    + Chỉnh sửa thuộc tính:
    – thêm
    – xóa
    – sửa tên & nội dung
    – Em xin cám ơn thầy trước, mong nhận được hướng dẫn của thầy qua Comment hay mail “huynhthidiu@yahoo.com”.

  10. Võ Văn Hải said

    Đã demo cho bạn. Xem tại:https://vovanhai.wordpress.com/xmlj/xml-simple-editor/
    Và bạn có thể xem thêm tại đây để làm cho bản của bạn thêm pro với 1 component hiển thị XML có màu sắc.

  11. Huynh Thi Diu said

    Em cảm ơn thầy nhiều, nhờ thầy mà em hiểu thêm về SAX, DOM

  12. Nguyễn Hữu Công Thành said

    Em chào thầy Hải ạ!
    Thầy cho em hỏi một vấn đề này với ạ:
    Hiện tại thì em đang học môn XML và thầy giáo của em có giao cho chúng em đề tài và ví dụ như thế này ạ:

    (hình trên là thầy giáo em lấy ví dụ về làm trên VB). Còn thầy yêu cầu là phải làm giao diện với các nút như trên được viết bằng ngôn ngữ java. Nhưng mà em thì chưa học ngôn ngữ Java nên hôm nay em vào đây và nhờ thầy giúp đỡ em ạ!
    Em xin chân thành cảm ơn…!

  13. Nguyễn Hữu Công Thành said

  14. Nguyễn Hữu Công Thành said

    em xin lỗi e không biết up cái ảnh e chụp lên đây, thưa thầy.
    thầy và các bạn có thể giúp em được không ạ. Em xin cảm ơn!

  15. Thưa thầy e cop code của thầy về chạy mà không được , e có add thư viện và down file xml về rồi , lúc chạy nó báo lỗi này ạ
    Exception in thread “AWT-EventQueue-0” java.lang.NoClassDefFoundError: org/apache/xerces/parsers/DOMParser
    at dom.swing.ParseTree.buildtree(ParseTree.java:138)
    at dom.swing.ParseTree.actionPerformed(ParseTree.java:348)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.AbstractButton.doClick(AbstractButton.java:376)
    at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:833)
    at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:877)
    at java.awt.Component.processMouseEvent(Component.java:6516)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3320)
    at java.awt.Component.processEvent(Component.java:6281)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4872)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4698)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2719)
    at java.awt.Component.dispatchEvent(Component.java:4698)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:694)
    at java.awt.EventQueue$3.run(EventQueue.java:692)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:708)
    at java.awt.EventQueue$4.run(EventQueue.java:706)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
    Caused by: java.lang.ClassNotFoundException: org.apache.xerces.parsers.DOMParser
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    … 40 more

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: