首頁  >  文章  >  後端開發  >  如何實現XML文件和JTree之間轉換

如何實現XML文件和JTree之間轉換

黄舟
黄舟原創
2017-05-07 14:08:542102瀏覽

XML因為良好的結構,被廣泛地應用於文件格式的定義。我們知道,應用軟體一般需要用設定檔來決定執行時的一些參數。以前的應用程式的設定檔一般是一個.ini檔。雖然現在,ini檔案仍然在使用,但由於XML的出現,越來越多的商用軟體正在把XML當作設定檔的格式,如BEA的Weblogic,以及IBM的Websphere等。所以,當我們設計一個軟體的設定檔時,將會越來越多地考慮使用XML作為該設定檔的格式。

而因為設定檔有時候必須讓使用者修改,所以提供一個視覺化的編輯設定檔的格式,是一個軟體具有良好的使用者可互動性的體現。我們必須給XML文件找到一個可視化的方法。 Java語言中的Swing元件裡面的JTree,用於XML文件的視覺化是非常適合的。這兩者之間存在著很方便的轉換方法。這就代表我們能將使用者在JTree上面的操作,在記憶體後方便地表現為在XML檔案中的修改,也能將XML檔案方便地表現為一棵JTree展現給使用者。

XML文件的視覺化

一個XML文件其實是一個樹狀的結構。例如下面這個XML文檔:

<?xml version=“1.0”encoding=“GB2312”?>
<skin>
  <skin1>
    <name>古典</name>
    <dir>d:\software\App\skin</dir>
    <head>head1.bmp</head>
    <center>center1.bmp</center>
    <foot>foot1.bmp</foot>
  </skin1>
<skin2>
    <name>现代</name>
    <dir>d:\software\App\skin</dir>
    <head>head2.bmp</head>
    <center>center2.bmp</center>
    <foot>foot2.bmp</foot>
  </skin2>
</skin>

可以看得出來,該XML文檔是一個多界面程序的界面圖片配置程序,如果將該XML文檔可視化,那麼使用JTree的話應該得到的是如下圖的結果。

如何實現XML文件和JTree之間轉換

圖 視覺化結果

所有的XML文檔,都​​能夠產生這樣一個Jtree。使用XML的Parser和Java裡的JTree類,可以建構出一個通用的視覺化XML文件從而構成一棵JTree。 XML Parser對XML文件解析的結果是產生一顆DOM(Document Object Model)樹,DOM樹的結構和JTree的結構其實是一樣的,這使得JTree和XML Parser的配合非常自然。下面就介紹一下做法。

一個讀寫XML檔的類別

首先必須取得XML Parser的包,可以從下面的網址取得:http://xml.apache.org/xerces2-j/index. html。
接著設計一個XMLTree的類,繼承自JTree類別的定義和成員變數函數定義如下:

public class XMLTree extends JTree{   
    private           DefaultMutableTreeNode      treeNode;  //JTree的根节点
    private           DocumentBuilderFactory     dbf; 
    // 这三个成员变量是xml parser需要的
    private           DocumentBuilder         db; 
    private           Document              doc;  
    XMLTree(String fileName);  
    //构造函数,做初始化工作
    public DefaultMutableTreeNode LoadFile(Node root);     
    //从某个XML文件生成该树
    public void SaveToFile(DefaultMutableTreeNode root,FileWriter fw);     
    //将该树存盘成XML文件
    private Node parseXml( String text )
}

其中建構函數所做的初始化工作如下:

XMLTree(String fileName){
      dbf = DocumentBuilderFactory.newInstance(); 
      //生成dbf的实例
      db = dbf.newDocumentBuilder();  
      //生成db的实例
      treeNode = LoadFile( getXMLRoot( text ) );  
      //解析该xml文件,返回JTree的根节点
      setModel( new DefaultTreeModel( treeNode ) );  
      //根据该根节点生成JTree
}

其中,parseXml是一個傳回XML檔根元素的程序,如下:

private Node getXMLRoot( String text ){
         ByteArrayInputStream    byteStream;
         byteStream = new ByteArrayInputStream( text.getBytes() ); 
         //将XML文件读到Stream里去
         try{
           doc = db.parse( byteStream );  
           //解析该xml文件。
         } catch ( Exception e )
         { e.printStackTrace();}
         return ( Node )doc.getDocumentElement();
            //返回该XML文件的DOM树的根元素
}

核心部分的LoadFile是一個遞歸過程,如下:

private DefaultMutableTreeNode createTreeNode( Node root ){
      DefaultMutableTreeNode  treeNode = null; 
         //定义要返回的根节点
      String name = root.getNodeName();
         //获得该节点的NodeName
         String value = root.getNodeValue(); 
         //获得该节点的NodeValue
     treeNode = new DefaultMutableTreeNode( root.
getNodeType() == Node.TEXT_NODE ? value : name );
      //如果为值节点,那么取得该节点的值,否则取得该节点的Tag的名字 
      if ( root.hasChildNodes() ) 
      //如果该节点有孩子节点,那么递归处理该节点的孩子节点
      {  NodeList children = root.getChildNodes();  
        //取得该节点的子节点列表
         if( children != null ){       
         //判断子节点是否为空
          int numChildren = children.getLength();  
           //取得字节数目
            for (int i=0; i < numChildren; i++){  
               Node node = children.item(i); 
                  //循环处理每个子节点
               if( node != null )
               {  if( node.getNodeType() == Node.ELEMENT_NODE )
                  { treeNode.add( createTreeNode(node) ); 
                  //如果该子节点还有孩子节点使用递归的方法处理该子节点
                  } else {
                 String data = node.getNodeValue();
                  if( data != null )
                  {
                     data = data.trim();
                     if ( !data.equals(“\n”) && !data.equals(“\r\n”) && 
data.length() > 0 )
                     {    treeNode.add(new 
DefaultMutableTreeNode(node.getNodeValue()));
                       //如果该节点没有孩子节点,那么直接加到节点下
                       }   
                   }  
                 } 
               } 
            }
         }
      } 
      return treeNode;  //返回节点 }

使用Java的Swing包裡的方法能夠輕鬆地在JTree上做改動,可以使用彈出對話框的方法,也可以直接在JTree上改動。總之,JTree改動後,需要重新寫回檔案中去將一棵JTree寫成XML檔案是一個遞歸的過程,方法如下:

public void SaveToFile(DefaultMutableTreeNode, FileWriter fw)
    {try {
      if (root.isLeaf()) fw.write(root.toString()+“\r\n”); 
//如果是叶子节点则直接将该节点输出到文件中
     else { //不是叶子节点的话递归输出该节点
      fw.write(“<”+root.toString()+“>\r\n”); 
     for (int i=0; i < root.getChildCount(); i++)
       { DefaultMutableTreeNode childNode =(DefaultMutableTreeNode) 
root.getChildAt(i);
         saveFile(childNode, fw); 
         //递归输出该节点的所有子节点 }
   fw.write(“</”+root.toString()+“>\r\n”);
    }
      } catch (Exception e)
      {  e.printStackTrace();
      } }

必須注意的是,如果XML檔案中包含中文,那麼需要在呼叫上面的函數之前,先在檔案中輸入該XML檔案的編碼方式,方法如下:

fw.write(“<?xml version=“1.0” encoding=“GB2312”?>\r\n”);

在呼叫該函數結束後,也應該關閉該文件,方法是:

fw.close()

結論

XML檔案廣泛地運用於設定檔、訊息傳遞中。它的視覺化方法有很多,本文透過結合Java的JTree類,介紹了其中一種實作方法。 Java語言和XML的良好結合,讓使用Java編製XML程式既靈活又方便。

以上是如何實現XML文件和JTree之間轉換的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn