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
Kết quả thu được như hình sau

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.
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!
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
vovanhai said
trong java, chỉ cần em chép thư viện (*.jar) theo chương trình của em là OK.
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
Võ Văn Hải said
Nè bạn: http://download.oracle.com/javase/tutorial/uiswing/components/tree.html
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)
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.
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”.
Võ Văn Hải said
Đã demo cho bạn. Xem tại:http://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.
Huynh Thi Diu said
Em cảm ơn thầy nhiều, nhờ thầy mà em hiểu thêm về SAX, DOM
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…!
Nguyễn Hữu Công Thành said
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!