Thursday

[XML]Xử lý XML file với SAX trong java (Phần 2)


Bạn cần đọc [XML]Xử lý XML file với SAX trong java (Phần 1)

Xử lý các element khi phân tích file XML.
Trong quá trình phân tích, khi gặp thẻ bắt đầu, phương thức  startElement() sẽ được gọi, khi gặp thẻ kết thúc phương thức endElement()sẽ được gọi, khi gặp một thẻ rỗng startElement() sẽ được gọi trước, sau đó là endElement().

Nếu cặp thẻ kết thúc vào bắt đầu không khớp SAXException sẽ được quăng ra. 
Các tham số của startElement()endElement() là:

public void startElement(String namespaceURI, String localName, String qualifiedName, Attributes atts)
    throws SAXException;
public void endElement(String namespaceURI, String localName, String qualifiedName)
    throws SAXException;
 
- namespaceURI là một string là namespace của file XML, nếu file xml không có namespace thì nó bằng null.
- localName: là phần sau của của một thẻ chứa dấu hai chấm. ví dụ nếu tên của thẻ là SOAP-ENV:Body thì localName là Body. Nếu tên thẻ không chứa hai chấm thì localName vẫn là Body.
- qualifiedName: tên đầy đủ của thẻ.
- atts: list các thuộc tính của thẻ.

Một ví dụ biểu diễn XML dưới dạng cây:

package jbohn.example.xml;

import java.util.EmptyStackException;
import java.util.Stack;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class TreeViewerContentHandler extends DefaultHandler {

    //Sử dụng stack như một danh sách tạm giúp xác định phần tử vào trước (cha)
    private Stack nodes;
    private TreeNode root;

    public void startDocument() throws SAXException 
    {
        nodes = new Stack();
    }

    public void startElement(String namespaceURI, String localName,
            String qualifiedName, Attributes atts) {

        String data;
        if (namespaceURI.equals(""))
            data = localName;
        else {
            data = '{' + namespaceURI + "} " + qualifiedName;
        }
        MutableTreeNode node = new DefaultMutableTreeNode(data);
        
        try {
            
            MutableTreeNode parent = (MutableTreeNode) nodes.peek();
            parent.insert(node, parent.getChildCount());
            
        } catch (EmptyStackException e) 
        {
            //phần tử đầu tiên stack không tồn tại sẽ quăng ra exception này.
            root = node;
        }
        nodes.push(node);

    }
    public void endElement(String namespaceURI, String localName,
            String qualifiedName) {
        nodes.pop();
    }
    public TreeNode getTreeNode()
    {
        return root;
    }
}
 
package jbohn.example.xml;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.util.EmptyStackException;
import java.util.Stack;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

public class XMLTreeviewer extends JFrame {

    private final static String xmlPath = System.getProperty("user.dir");
    private static TreeNode root;

    /**
     * Launch the application.
     */
    public static void main(String[] args) 
    {
        EventQueue.invokeLater(new Runnable() 
        {
            public void run() {
                try {
                    
                    String xmlFile = xmlPath + "\\XML_SAX.xml";
                    XMLReader parser = XMLReaderFactory.createXMLReader();
                    ContentHandler handler = new TreeViewerContentHandler();
                    parser.setContentHandler(handler);
                    parser.parse(xmlFile);
                    root = ((TreeViewerContentHandler) handler).getTreeNode();
                    XMLTreeviewer main = new XMLTreeviewer();
                    
                } catch (Exception e) {
                    System.err.println(e);
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public XMLTreeviewer() 
    {
        createGUI();
    }
    
    public void createGUI()
    {
        JTree tree = new JTree(root);
        JScrollPane treeView = new JScrollPane(tree);
        this.setTitle("XML Tree");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.getContentPane().add(treeView);
        this.pack();
        this.setVisible(true);
    }

} 


 

Wednesday

[XML]Xử lý XML file với SAX trong java (Phần 1)


SAX, viết tắt của: the Simple API for XML:

SAX được thiết kế gồm các interface (hoặc các abstract class) thay vì các lớp xử lý cố định, có thể hiểu là lớp trên của bộ phân tích nguyên thủy. Chúng ta có thể hiện thực lại các phương thức trong các interface của SAX tùy cách sử dụng.

SAX có hai interface cơ bản là:
+ XMLReader: gồm thực hiện việc đọc file XML và phân tích file đó bằng cách gọi các phương thức của ContentHandler.
+ ContentHandler: gồm các phương thức xử lý việc nhận dữ liệu từ việc phân tích.

SAX được thiết kế theo Observer design pattern. XMLReader đóng vai trò là Subject và ContentHandler đóng vai trong là các Observer. Nhưng mỗi thực thể XMLReader chỉ cho phép đăng ký một listener.

* Sử dung XMLReader: chúng ta sẽ sử dụng hàm tạo thực thể XMLReader mặc định của lớp XMLReaderFactory.

Tạo thực thể XMLReader và gọi hàm parse:

package jbohn.example.xml;

import java.io.IOException;

import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

public class SAXexample 
{
    private final static String xmlPath = System.getProperty("user.dir");
    
    public static void main(String[] args) 
    {
        XMLReader xmlReader;
        String xmlFile = xmlPath + "\\XML_SAX.xml"; //click on xmlFile to download it
        
        try 
        {
            xmlReader = XMLReaderFactory.createXMLReader();
            xmlReader.parse(xmlFile);
            System.out.println("Parsed " + xmlFile + " sucessfully");
        }
        catch (SAXException e) 
        {
            System.out.println(xmlFile + " is not well-formed");
        } 
        catch (IOException e) 
        {
            System.out.println("Cannot acess to or read file" + xmlFile);
        }
    }
}
 
 * Sử dụng ContentHandler: Hầu hết các trường hợp chúng ta phải hiện thực lại các phương thức của interface này.

Các methods được khai bào trong ContentHandler:
package org.xml.sax;

public interface ContentHandler 
{

  public void setDocumentLocator(Locator locator);
  public void startDocument() throws SAXException;
  public void endDocument() throws SAXException;
  public void startPrefixMapping(String prefix, String uri)
   throws SAXException;
  public void endPrefixMapping(String prefix) 
   throws SAXException;
  public void startElement(String namespaceURI, String localName,
   String qualifiedName, Attributes atts) throws SAXException;
  public void endElement(String namespaceURI, String localName,
   String qualifiedName) throws SAXException;
  public void characters(char[] text, int start, int length)
   throws SAXException;
  public void ignorableWhitespace(char[] text, int start, 
   int length) throws SAXException;
  public void processingInstruction(String target, String data)
   throws SAXException;
  public void skippedEntity(String name)
   throws SAXException;

}
 
Khi chúng ta cần phân tích một file XML chúng ta sẽ hiện thực các phương thức trong ContentHandler. DefaultHandler là lớp đã hiện thực các phương thức trên. ContentHandler tùy biến (các bạn tự implement việc xử lý các thành phần trong file xml) sẽ kế thừa từ DefaultHandler hoặc implement ContentHandler. Ví dụ khi parser gặp thẻ bắt đầu nó sẽ gọi startDocument, cần gặp thẻ kết thúc nó sẽ gọi endDocument, cần đọc nội dung của trong thẻ nó đọc characters,... khi đó tùy vào mục đích các bạn sẽ hiện thực cá phương thức đó.


package jbohn.example.xml;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SaxHandler extends DefaultHandler 
{
    public void startDocument() throws SAXException 
    {
        System.out.println("start document   : ");
    }

    public void endDocument() throws SAXException 
    {
        System.out.println("end document     : ");
    }

    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException 
    {

        System.out.println("start element    : " + qName);
    }

    public void endElement(String uri, String localName, String qName)
            throws SAXException 
    {
        System.out.println("end element      : " + qName);
    }

    public void characters(char ch[], int start, int length)
            throws SAXException 
    {
        System.out.println("start characters : "
                + new String(ch, start, length));
    }

}
 
Output: 
start element    : book
start characters :
    
start element    : author
start characters : Gambardella, Matthew
end element      : author
start characters :
    
start element    : title
start characters : XML Developer's Guide
end element      : title
start characters :
    
start element    : genre
start characters : Computer
end element      : genre
start characters :
    
start element    : price
start characters : 44.95
end element      : price
start characters :
    
start element    : publish_date
start characters : 2000-10-01
end element      : publish_date
start characters :
    
start element    : description
start characters : An in-depth look at creating applications
      with XML.
end element      : description
start characters :
 
end element      : book

Trong phần tới chúng ta sẽ tìm hiểu về một số cách hiện thức các phươn thức trong  ContentHandler.

Saturday

MVC pattern in Android


This is an example of implementation MVC pattern in android development.

Calculator application

- MainActivity is the application execution, there is only CalculatorActivity, which is responsible for the GUI, event handling and display of visual objects.
- JModel: maintains state of the calculator.
- JView: display of model state, the state of the calculator.
- JController: receives user input via button onClick events, sends user input to Model, and sends "Model state" to myView.











Class JController:

package com.example.mvcpatternandroid;

import com.example.mvcpatternandroid.R;

import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;

/**
 * copyright (c) jbohn
 */
public class JController implements OnClickListener {

    JModel myModel = null;
    JView myView = null;

    public JController(final JModel myModel, final JView myView) 
    {
        this.myModel = myModel;
        this.myView = myView;
        this.myView.registerListener(this);
    }

    public void onClick(View v) {

        switch (v.getId()) {
        case R.id.button0:
            myModel.setModel('0');
            break;
        case R.id.button1:
            myModel.setModel('1');
            break;
        case R.id.button2:
            myModel.setModel('2');
            break;
        case R.id.button3:
            myModel.setModel('3');
            break;
        case R.id.button4:
            myModel.setModel('4');
            break;
        case R.id.button5:
            myModel.setModel('5');
            break;
        case R.id.button6:
            myModel.setModel('6');
            break;
        case R.id.button7:
            myModel.setModel('7');
            break;
        case R.id.button8:
            myModel.setModel('8');
            break;
        case R.id.button9:
            myModel.setModel('9');
            break;
        case R.id.buttonPlus:
            myModel.setModel('+');
            break;
        case R.id.buttonDivide:
            myModel.setModel('/');
            break;
        case R.id.buttonMinus:
            myModel.setModel('-');
            break;
        case R.id.buttonTimes:
            myModel.setModel('*');
            break;
        case R.id.buttonC:
            myModel.setModel('C');
            break;
        case R.id.buttonEqual:
            myModel.setModel('=');
            break;
        }
        myView.setView(myModel.getModel());
    }
}
 
* Class JView 
 
package com.example.mvcpatternandroid;

import com.example.mvcpatternandroid.R;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;


/**
 * @author QuocTrinh
 * copyright (c) jbohn
 */
public class JView extends LinearLayout {
    private EditText txtDisplay;
    LayoutInflater layoutInflater;
    public JView(Activity activity) 
    {
        super(activity, null);
        
        this.setOrientation(VERTICAL);
        
        getInFlater(activity);
        
        getTxtView();
    }


    private void getInFlater(Activity activity) 
    {
        layoutInflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    
    private void getTxtView() {
        layoutInflater.inflate(R.layout.display, this);
        txtDisplay = (EditText) findViewById(R.id.editString);
    }

    public void setView(String s) {
        txtDisplay.setText(s);
    }
    
    public void registerListener(OnClickListener onClickListener) {
        
        View view = (View) layoutInflater.inflate(R.layout.keyboard, this);
        
        final Button button0 = (Button) view.findViewById(R.id.button0);
        final Button button1 = (Button) view.findViewById(R.id.button1);
        final Button button2 = (Button) view.findViewById(R.id.button2);
        final Button button3 = (Button) view.findViewById(R.id.button3);
        final Button button4 = (Button) view.findViewById(R.id.button4);
        final Button button5 = (Button) view.findViewById(R.id.button5);
        final Button button6 = (Button) view.findViewById(R.id.button6);
        final Button button7 = (Button) view.findViewById(R.id.button7);
        final Button button8 = (Button) view.findViewById(R.id.button8);
        final Button button9 = (Button) view.findViewById(R.id.button9);
        final Button buttonC = (Button) view.findViewById(R.id.buttonC);
        final Button buttonPlus = (Button) view.findViewById(R.id.buttonPlus);
        final Button buttonEqual = (Button) view.findViewById(R.id.buttonEqual);
        final Button buttonMinus = (Button) view.findViewById(R.id.buttonMinus);
        final Button buttonTimes = (Button) view.findViewById(R.id.buttonTimes);
        final Button buttonDivide = (Button) view
                .findViewById(R.id.buttonDivide);

        button0.setOnClickListener(onClickListener);
        button1.setOnClickListener(onClickListener);
        button2.setOnClickListener(onClickListener);
        button3.setOnClickListener(onClickListener);
        button4.setOnClickListener(onClickListener);
        button5.setOnClickListener(onClickListener);
        button6.setOnClickListener(onClickListener);
        button7.setOnClickListener(onClickListener);
        button8.setOnClickListener(onClickListener);
        button9.setOnClickListener(onClickListener);
        buttonC.setOnClickListener(onClickListener);
        buttonPlus.setOnClickListener(onClickListener);
        buttonEqual.setOnClickListener(onClickListener);
        buttonMinus.setOnClickListener(onClickListener);
        buttonTimes.setOnClickListener(onClickListener);
        buttonDivide.setOnClickListener(onClickListener);
    }

} 

* Class JModel
package com.example.mvcpatternandroid;

/**
 * @author QuocTrinh
 * copyright (c) jbohn
 */
public class JModel {
    private double accumulator, opr;
    private char op;

    public JModel() {
        accumulator = 0.0;
    }

    public void setModel(char c) {
        switch (c) {
        case 'C':
            opr = 0.0;
            accumulator = 0.0;
            break;
        case '+':
            ;
        case '-':
            ;
        case '*':
            ;
        case '/':
            op = c;
            opr = accumulator;
            accumulator = 0.0;
            break;
        case '=':
            switch (op) {
            case '+':
                accumulator = opr + accumulator;
                break;
            case '-':
                accumulator = opr - accumulator;
                break;
            case '*':
                accumulator = opr * accumulator;
                break;
            case '/':
                accumulator = opr / accumulator;
                break;
            default:
            }
            break;
        default: // Assume '0'..'9' digit
            accumulator = accumulator * 10.0 + (c - '0');
            break;
        }
    }

    public String getModel() {
        return accumulator + "";
    }
}
 
Download Source code (http://jbohn.blogspot.com/)
 

Example of MVC in Java


A component diagram has been used to describe MVC pattern.

Download  MVC Example
 
- ModelThis component contains one or more classes and interfaces that are responsible for maintaining the data model. The state of the model is kept in attributes and the implementation of methods. To be able to notify view components of any change in the model, the model keeps a reference to each registered view (there can be more than one at the same time). When a change occurs, every view component that has registered should be notified.

- View – The classes and interfaces of the view provide a representation of the data in the model component. The view may consist of visual GUI components, but is not required to. A view must be registered with the model to be notified of changes to the model data. When a notification of such a change is received, the view component is responsible for determining if and how to represent this change. The view component also keeps a reference to the model to retrieve data from the model, but it can only retrieve information, not change it. The view can also be used to render the controller, but requests for change are always forwarded to a controller component; so the view needs to keep a reference to one or more controllers.

 But not all views require a controller, some view provide a visual presentation of data, but don't support any changes to model from that view.

- ControllerThis component manages changes to the model. It keeps a reference to the model component who is responsible for carrying out the change, whereas the controller calls one or more update methods. The requests for change may come from a view component.

Thursday

Sublime Text 2 Compile and Run Java Code


Sublime text 2 is a great text editor. What makes it even better is the ability to compile and run Java code. It seems that there is a lot of confusion on how to get Java to compile and run on Windows machines using Sublime Text 2. So in short, here is my first tutorial:

1) Install sublime text 2 here.
2) Install the JDK (Java Developers Kit) from here.
3) After the JDK has been installed, locate the bin folder path in the JDK install directory. Mine is”C:\Program Files\Java\jdk1.6.0\bin\”.
4) You will now need to modify the path value to prevent any syntax errors from occuring. To do this, add double slashes where there is a single slash in the JDK bin path. E.g: C:\\Program Files\\Java\\jdk1.6.0\\bin\\.
5) Open Sublime Text 2 and go to Preferences > Browse Packages
6) In the browser window that popped up go to the Java folder
7) Open the file JavaC.sublime-build and replace all the code in the file with the code below:
{
 "cmd": ["javac", "$file_name","&&","java", "$file_base_name"],
 "file_regex": "^(...*?):([0-9]*):?([0-9]*)",
 "path": "C:\\Program Files\\Java\\jdk1.6.0\\bin\\",
 "selector": "source.java",
 "shell": true
 }
8) Make sure you substitute the path with your own JDK bin path. Don’t forget to save your file.
9) In Sublime Text 2 select Tools > Build System > JavaC. Confirm that JavaC has a check mark next to it.
10) Open up your java file and compile and run it by going to Tools > Build. You can use the shortcut ctrl+b.

Re-post from: http://www.ryanburch.me/sublime-text-2-compile-and-run-java-code/