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的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文档和JAVA中的JTree之间如何转换的问题的更多相关文章

  1. Java中数据类型及其之间的转换

    Java中数据类型及其之间的转换 基本的数据类型 基本类型有以下四种:1)int长度数据类型有:byte(8bits).short(16bits).int(32bits).long(64bits).2 ...

  2. Java中数据类型及其之间的转换(转)

    Java中数据类型及其之间的转换 基本的数据类型 基本类型有以下四种:1)int长度数据类型有:byte(8bits).short(16bits).int(32bits).long(64bits).2 ...

  3. XML文档形式&JAVA抽象类和接口的区别&拦截器过滤器区别

    XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式? a: 两种形式 dtd schemab: 本质区别:schema本身是xml的,可以被XML解析器解析(这也是从DTD上发 ...

  4. JAVA读取XML,JAVA读取XML文档,JAVA解析XML文档,JAVA与XML,XML文档解析(Document Object Model, DOM)

    使用Document Object Model, DOM解析XML文档 也可参考我的新浪博客:http://blog.sina.com.cn/s/blog_43ac5543010190w3.html ...

  5. java中进制之间的转换

    //十进制转其他进制 Integer.toHexString(10); //将10转换为十六进制,返回字符串类型 Integer.toOctalString(10); //将10转为八进制,返回字符串 ...

  6. JAVA对象和XML文档、原来他们之间还有这一出

    最近项目开发中遇到一个问题,访问接口不再通过url地址请求的方式,而是 通过socket发送xml格式的报文到指定服务器来进行信息的统一认证.. 因此组装xml格式的报文字符串以及解析服务器返回的xm ...

  7. Java高级特性 第15节 解析XML文档(3) - JDOM和DOM4J技术

    一.JDOM解析 特征: 1.仅使用具体类,而不使用接口. 2.API大量使用了Collections类. Jdom由6个包构成: Element类表示XML文档的元素 org.jdom: 解析xml ...

  8. DOM和SAX是应用中操纵XML文档的差别

    查看原文:http://www.ibloger.net/article/205.html DOM和SAX是应用中操纵XML文档的两种主要API.它们分别解释例如以下:          DOM.即Do ...

  9. java: (正则表达式,XML文档,DOM和DOM4J解析方法)

    常见的XML解析技术: 1.DOM(基于XML树结构,比较耗资源,适用于多次访问XML): 2.SAX(基于事件,消耗资源小,适用于数量较大的XML): 3.JDOM(比DOM更快,JDOM仅使用具体 ...

  10. 使用DOM解析XML文档

    简单介绍一下使用DOM解析XML文档,解析XML文件案例: <?xml version="1.0" encoding="UTF-8"?> -< ...

随机推荐

  1. Windows 11 上搭建 Linux 桌面系统

    为什么做这个事呢?首先dev 环境方面肯定Linux是主流,然后因为后面要跑CV应用,肯定还是要看看效果啥的,最好有个桌面系统. 1. 首先在windows 里安装 WSL, 要用 wsl2 版本 2 ...

  2. C++17: 用折叠表达式实现一个IsAllTrue函数

    前言 让我们实现一个 IsAllTrue 函数,支持变长参数,可传入多个表达式,必须全部计算为true,该函数才返回true. 本文记录了逐步实现与优化该函数的思维链,用到了以下现代C++新特性知识, ...

  3. 常回家看看之house_of_kiwi

    house of kiwi 前言:house_of_kiwi 一般是通过触发__malloc_assert来刷新IO流,最后可以劫持程序流或者通过和setcontext来打配合来进行栈迁移来得到fla ...

  4. C# Dynamic 转换成 Dictionary,Dynamic 转换成 DataTable

    部分软件开发的时候用到了 dynamic 类型,这个类型的数据不需要做其他处理的时候非常好用,但是需要对其中的数据调整的时候就不是那么好用了,这里提供两个常见的转换方式 Dynamic To Dict ...

  5. vue源码解析-实现一个基础的MVVM框架

    基本介绍 vue.js采用数据劫持结合发布-订阅模式的方式,通过Object.defineProperty()来劫持各个属性的getter,setter,在数据变动时发布消息给订阅者,触发响应的监听回 ...

  6. Qml 实现水波进度动画条

    [写在前面] 最近看到一个非常有趣的动画效果:水波进度动画. 学习了一下实现思路,觉得很有意思. 不过原版是 HTML + CSS,我这里用的是 Qml,有一些小技巧,分享给大家~ [正文开始] 老样 ...

  7. MDC – Text field

    前言 Angular Material 只有 Form field, 但 Material Design 有份 Text field 和 Form field, Form field 是给 check ...

  8. dfs与贪心算法——洛谷5194

    问题描述: 有n个砝码,将砝码从大到小排列,从第三个砝码开始,所有砝码均大于其前两个砝码之和,问怎样的砝码组合才可以组合出不大于c的最大重量,输出该重量 输入: 第一行输入两个个整数N,c,代表有N个 ...

  9. [TK] 理想的正方形

    题目描述 有一个整数组成的矩阵,现请你从中找出一个指定边长的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 题目分析 其实这道题和滑动窗口很像,而滑动窗口使用优先队列解决. 我们都知道优先队 ...

  10. RedisTemplate设置的key,redis客户端取不到

    原因:RedisTemplate 在set key时,key被序列化 解决办法1: import org.springframework.context.annotation.Bean; import ...