我想您一定對xml有所了解,說不定您現在還躍躍欲試想寫一段XML文本呢,可是現在能找到的跨平台的、免費的XML編輯器太少了。所以在本文中,我想介紹一下或是帶您一步一步的開發一個簡單的XML編輯器,當然我們要用到一些最常見的Java 2 Swing元件,不過這些都是免費的,有些是JDK中的,有些是可以從網路下載的。我想透過本文,你就可以建立一個屬於你自己的XML編輯器。
先讓我介紹一下本文輯寫的思路。首先我想簡要的討論一下XML和為什麼樹型結構比較適合用來顯示XML,然後我們來看看JAXP API如何建立所需的XML類別的環境;然後我們將了解用來顯示一個圖形樹的JTree Swing元件;最後,我們將建立一個繼續JTree元件的可以重複使用的類,可以用來分析一個XML文檔,並把資料顯示在一個Jtree中。
說到XML(eXtensible Markup Languge),人們往往把它當成是一種新的用於Web瀏覽器中的標記語言,就像Html或CSS一樣。其實,XML是一種資料表示語言,它答應你使用一個非常有效的方法來描述你的資料。 XML能夠讓你定義諸如「these three Words constitutes a heading」這樣的語句。 XML答應你聲明任何類型的數據,而不是用來把這些數據顯示在網頁中。
請看一看下面的XML實例:
<article>
<header>
<title> 使用Java Swing 創建一個XML編輯器
<< author > Wayne </author>
<header>
<content> 這是正文</content>
</article>
語請注重,這些元素和標準的去比較這是因為XML和HTML都是來自SGML語言。不同的是HTML有預先定義的標籤集,而XML的語法則有許多彈性,它答應你使用表意的標記如<author>來括在資料兩邊。你也要注重,所有的元素都從屬於根元素(上例中為<article>),有些元素則還有自己的子元素,如<subtitle>就是<title>的子元素。這樣的資料組織方式有三個好處:資料能夠更加表意,資料更加易於維護而且資料更加輕易作為一個樹的結構表現出來,這就是我們為什麼使用JTree物件來顯示XML資料的原因。假如你想對XML有更深的了解,請參考天極網上的相關教學。
JAXP是一個用於處理XML的Java API,它能夠使應用程式分析並且轉換XML文件,它的功能有點象JDBC API,都是把函數功能抽象成一個個方法。你可以去Apache網站找到最新的Xerces分析器,裡面有最新的JAXP,下載下來以後把它放在你的類別目錄中。
下面讓我們來看看如何使用JTree Swing元件。
我們都知道,在自然界中,一棵樹通常都有一個非常粗的樹幹,樹幹上有許多樹枝分叉。每個樹杈和樹杈之間都有一定的聯繫,因為它們都有同一個來源:樹幹。這種持續的關係並不只在樹枝中有,人類譜係也遵循相同的規律。從父母,到子女再到子女的子女,就這樣直到數不清為止。同樣,在資料儲存中,樹的概念也是一種使用同人類家譜樹一樣方法儲存資料的方法。樹的每一個樹杈稱為一個節點,每個有子節點的節點稱為父節點,所有的子節點的公共的父節點稱為根節點。一個JTree組件就是一個簡單的樹資料結構的視覺化表現形式。
幾乎所有的XML編輯器都包含一個可視化的樹結構,能讓你編輯XML文件中的元素。我們馬上就會建立一個編輯器,不過在此之前,先讓我們再了解一下JTree元件。一個節點在一棵樹的某個位置儲存數據,為了儲存數據,必須知道任何一個父節點和它們的子節點。 javax.swing.tree套件定義了一些非常有用的接口,提供了一個通用的方法來建構和操作一個樹結構。
TreeNode方法,用於存取樹的節點的資訊
MutableTreeNode方法 用在一個可變的樹上(能夠添加或刪除子節點)
TreeModel 能夠添加或刪除子節點)
TreeModel 方法用於建立和治理樹相關的資料模型。
接下來,我們將創建一個繼續JTree的類,提供分析XML文件和用可視化JTree組件把節點顯示出來的功能。
創建XTree組件
XTree類別由一個構造函數和三個方法組成,為了簡單起見我們的組件只能建構一個Xtree,在樹創建好之後不能進行處理它的節點。下面讓我們來看一個這個類別。
域:
PRivate DefaultMutableTreeNode treeNode 這個成員變數儲存TreeNode物件用於儲存JTree的模型。
DefaultMutableTreeNode類別是在javax.swing.tree中被定義的,預設提供了MutableTreeNode介面的一個實作。
private DocumentBuilderFactory dbf
private DocumentBuilder db
private Document doc這三個成員變數是JAXPcumentBuilder 的一部分,用來分析文字並轉換成一個對物件進行分析。
建構子
public XTree( String text )
這個建構子透過使用傳送到建構器中的XML文字建立一個XTree物件。在初始化一些與JTree超類別和DOM分析物件相關的基本顯示屬性後,建構函式產生一個TreeModel 物件用來建立一個實際可視的樹。透過把DOM物件傳送到createTreeNode()方法來建立一個根節點,createTreeNode()方法傳回一個DefaultMutableTreeNode類型的物件。這個物件然後被用來建立樹的TreeModel。
方法
private DefaultMutableTreeNode createTreeNode( Node root )
這個方法採用一個都被歸納到子節點中遞歸到所有的接點中遞歸到所有的接點。這是一個遞歸方法,為了找到根節點下的每一個子節點,它每次都要呼叫自己。 JTree接著就可以使用DefaultMutableTreeNode物件了,因為它已經是樹型了。
private String getNodeType( Node node )
這個方法,被createTreeNode()用來聯繫一個字串和某一種類型的節點。
private Node parseXml()
這個方法,用來分析XML文字字串,它傳回Node類型的對象,能夠被傳送到createTreeNode()方法中。
下面我給了java程式碼,供大家分析研究。
// 到入W3C的DOM 類別
import org.w3c.dom.*;
// JAXP的用於DOM I/O的類別
import javax.xml.parsers.*;
// 標準盤類別
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java. .*;
public class XTree extends JTree
{
/**
* 這個成員變數儲存TreeNode物件用來儲存JTree的模型。
*DefaultMutableTreeNode類別是在javax.swing.tree中被定義的
*預設提供了MutableTreeNode介面的實作。
*/
private DefaultMutableTreeNode treeNode;
/**
* 這三個成員變數是JAXP的一部分,用來分析XML文字並轉換成DOM(Document Object Model) 物件。
*/
Builderfate Documentdby dbf;
/**
* 這個建構子透過使用傳送到建構器中的XML文字建立一個XTree物件
* @參數text是一個XML格式的XML文字
* @異常ParserConfigurationException 假如建構子非正常的設定分析器,就會正常的設定分析器,就會正常的設定分析器,就會正常的設定分析器,就會正常的設定分析器,就會拋出異常
*/
public XTree( String text ) throws ParserConfigurationException
{
super();
// 設定Tree渲染的基本屬性
super();
// 設定Tree渲染的基本屬性
sRootHandles ( true );
setEditable( false ); // 答應樹可以編輯
// 透過初始化物件的DOM來分析物件
dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating( false ); newDocumentBuilder();
// 採用DOM根節點並且把它轉換成JTree的樹模型
treeNode = createTreeNode( parseXml( text ) );
setfilel( new DefaultTreeModel( treeNode ) );
setfilel( new DefaultTreeModel( treeNode ) ); ()
/**
* 這個方法採用一個DOM 節點,然後在子節點中遞歸直到所有的接點都被加入到DefaultMutableTreeNode中。
* 這是一個遞歸方法,為了找到根節點下的每一個子節點,它每次都要呼叫自己。
* JTree然後就可以使用DefaultMutableTreeNode物件了,因為它已經是樹型了。
*
* @參數 root org.w3c.Node.Node
*
* @ */
private DefaultMutableTreeNode createTreeNode( Node root )
{
DefaultMutableTreeNode treeNode = nulld^g // 從在根節點取得資料
type = getNodeType( root );
name = root.getNodeName();
value = root.getNodeValue();
treeNode = new DefaultMutableTreeNode( root.getNodeType() == Node. : name );
// 顯示屬性
attribs = root.getAttributes();
if( attribs != null )
{
for( int i = 0; i < attribs.getLength); igetLength); attribNode = attribs.item(i);
name = attribNode.getNodeName().trim();
value = attribNode.getNodeValue().trim();
if ( value != null )
{
( .length() > 0 )
{
treeNode.add( new DefaultMutableTreeNode( "[Attribute] --> " + name + "="" + value + """ ) );
} file://end if (value.length() > 0 )
} file://end if ( value != null )
} file://end for( int i = 0; i < attribs.getLength(); i++ )
} file://end if( attribs != null )
// 假如存在子節點,遞歸
if( root.hasChildNodes() )
{
NodeList children;
int numChildren;
Node node;
String data;
int numChildren;
Node node;
String data;
int numChildren;
Node node;
String;假如子節點非空的話,只遞歸
if( children != null )
{
numChildren = children.getLength();
for (int i=0; i < numChildren; i) item(i);
if( node != null )
{
if( node.getNodeType() == Node.ELEMENT_NODE )
{
treeNode.add( createTreeifNode(node) );
{
treeNode.add(file://end ifNode(node) );
} ://end Node.add(file://end ifNode(node) );
} ( node.getNodeType() == Node.ELEMENT_NODE )
data = node.getNodeValue();
{
data = data.trim();if ( data.equif " ") && !data.equals("