好东西大家分享:java&xml的学习心得(1)

4/7/2006来源:Java认证人气:10480

最近一段时间有空,啃了啃xml和与它相关的东东,做了一些实践性的代码和功能,做完后自己都不怎么满意,不过实践过程到是一个新手的典型例子。所以拿出来让高手指点指点。^_^

由于一直做b/s结构的东西,在加上一个做项目中的遗留问题(tree型角色和tree型权限之间的交互),所以想做一个xml的解决方案。

   当然这个问题的解决必须有对xml文档对象操作的模块的支持。这篇心得主要针对这个问题。

   设计图如下:


   XMLParser.class:xml解析器接口。

   XMLParserTest.class:xml解析器接口实现子类。

   XMLParserFactory.class :xml解析器工厂类。

   XMLTool.class :xml工具类接口(对xml文档进行操作)。

   XMLToolTest.class :xml工具类接口实现子类。

   XMLToolShow.class :{xml工具类接口实现子类(所有方法的实现都是用XMLTool接口的对应方法实现,功能是通过setForm()灵活更换自己的兄弟类(XMLTool)作为 XML处理工具来获得更好的效率和完善。}

   XMLToolFactory.class :xml工具类工厂类。

   还有两个设计图中没有的class:

   XmlBuilder.class :根据指定的document.Node生成规范的xml字符串。

   XmlOutput.class :根据指定的xml字符串或InputStream生成指定的xml文件。

   我在 XMLParserTest.class用到的是xml4j解析器.代码如下:

package com.ceic.workflow.xml.Parser;

import com.ceic.workflow.xml.XMLParser;
import com.ibm.xml.parsers.*;
import java.io.*;
import org.xml.sax.InputSource;
/**
* XML解析器test
* Title: XML解析器test
* Description: XML解析器test
* Copyright: Copyright (c) 2003
* Company: 国电信息中心
* @author 张治中
* @version 1.0
*/
public class XMLParserTest implements XMLParser
{

public XMLParserTest()
{

}

/**
* 解析path位置的xml文件
* @param path 文件位置
* @param vali 备用参数
* @return Object
* @roseuid 3ECC2FC10043
*/
public Object parse(String path, boolean vali)
{
if(path!=null&&path.length()>0){
try{
DOMParser parser = new DOMParser();
parser.parse(path);
return parser.getdocument.)
}catch(Exception e){
System.out.PRintln(\"XMLParserTest.parse(\\\"\"
+path+\"\\\",\"+vali+\")出错\"+e.getMessage());
return null;
}
}
return null;
}

/**
* 解析xmlString字符串
* @param xmlString xml字符串
* @return Object
* @roseuid 3ECC2FC10043
*/

public Object parseString(String xmlString)
{
if(xmlString!=null&&xmlString.length()>0){
try{
DOMParser parser = new DOMParser();
StringReader rd=new StringReader(xmlString);
InputSource in=new InputSource(rd);
parser.parse(in);
return parser.getdocument.)
}catch(Exception e){
System.out.println(\"XMLParserTest.parseString
(\\\"\"+xmlString+\"\\\")出错\"+e.getMessage());
return null;}
}
return null;
}
}
   XMLParserFactory.class用普通手动注册方式。高手可以指点一下好的解决方法。代码如下:

package com.ceic.workflow.xml;

import com.ceic.workflow.xml.Parser.XMLParserTest;
import java.util.*;
/**
* XML解析器工厂
*/
public class XMLParserFactory
{
private static Hashtable table;
private static String defaultType;

private XMLParserFactory()
{
}

/**
* 获得XML解析器
* @param parserType XML解析器类型
* @param parserClassName XML解析器类名
* @return com.ceic.workflow.xml.XMLParser
* @roseuid 3ECB39E30029
*/
public static XMLParser getXMLParser
(String parserType, String parserClassName)
{
try{
if(parserType==null||parserType.length() <=0){
parserType=defaultType;
}
if(table.containsKey(parserType)){
return ((XMLParser)Class.forName(table.
get(parserType).toString()).newInstance());
}
if(parserClassName!=null&&parserClassName.length() >0){
try{
XMLParser temp=((XMLParser)Class.
forName(parserClassName).newInstance());
if(parserType!=null&&parserType.length() >0){
table.put(parserType,parserClassName);
}
return temp;
}catch(Exception ee){
System.out.println(ee.getMessage() );
System.out.println(\"指定的XML解析器不存在\");
return null;
}
}
return null;
}catch(Exception e){
System.out.println(e.getMessage() );
System.out.println(\"指定的XML解析器不存在\");
return null;
}
}
public static String getDefaultType(){
return defaultType;
}

static
{
table=new Hashtable();
table.put(\"dom\",\"com.ceic.workflow.xml.
Parser.XMLParserTest\");
defaultType=\"dom\";
}
}

   其中getXMLParser(String parserType, String parserClassName)如果是调用已知(已注册)XMLParser,第2个参数可以是null或\"\"
   接口 XMLTool.class是主要的外界操作界面。代码如下:

package com.ceic.workflow.xml;
import org.w3c.dom.*;

/**
* Title: XML处理工具的 运算和实现部分 的接口
* Description: XML处理工具的 运算和实现部分 的接口
* Copyright: Copyright (c) 2003
* Company: 国电信息中心
* @author 张治中
* @version 1.0
* XML处理工具的 运算和实现部分 的接口
*/
public interface XMLTool
{

/**
* 通过解析器把指定的xml文件解析生成java对象。
* 例如org.w3c.dom.document.
* @param path - xml文件路径(包括文件名).
* @param vali - 备用参数。和XMLParser中的parse
* (String path,boolean vali)对应。默认为false.
* @return Object
* @roseuid 3ECC1EAB0007
*/
public Object Build(String path, boolean vali);
/**
* 通过解析器把指定的xml字符串解析生成java对象。
* 例如org.w3c.dom.document.
* @param xmlString xml字符串
* @return Object
* @roseuid 3ECC1EAB0007
*/
public Object Build(String xmlString);
/**
* 设定document.
* @param docs -document.
*/
public void setdocument.ource(document.nbspdocs);

/**
* 设定XML解析器,各个解析器差别较大,
* 建议在class中固化解析器.
* @param ParserName - 解析器名称
* @param ClassName -
* 解析器class名,如果是已知解析器(XMLParserFactory中固化的),
* 可以传null或空字符串
* @roseuid 3ECC1EBA0366
*/
public void setParser(String ParserName,
String ClassName);

/**
* 设定指定节点的单个属性
* @param NodeName 节点名
* @param propertyName attribute名,
* 如果为空则指定NodeName节点的节点值
* @param value attribute或节点的值
* @param setall 是否全部的节点都更新
* @roseuid 3ECB3FA50317
*/

public void setProperty(String NodeName,String
propertyName,String value,boolean setall);
/**
* 获得指定节点的单个属性
* @param NodeName 节点名
* @param propertyName attribute名,
* 如果为空,就找出节点的值
* @return String
* @roseuid 3ECB3FA50317
*/
public String getProperty(String NodeName,
String propertyName);
/**
* 获得指定节点名的所有节点的指定属性
* @param NodeName 节点名
* @param propertyName attribute名,
* 如果为空,就找出节点的植
* @return String[]
* @roseuid 3ECB3FA50317
*/
public String[] getPropertys(String NodeName,
String propertyName);

/**
* 从XMLToolFactory中获得XMLTool做为对XML文档操作的基础。
* @param XMLToolName - XMLTool在工厂类中的type名。
* @param classname - XMLTool的class名。
* 默认为null或空字符串。
* @roseuid 3ECC1D870379
*/
public void setFormat(String XMLToolName,
String classname);

/**
* 在所有parent节点或指定的parent节点处(具体位置由setMarkSign(),
* setMark()或setMarkAdv()来确定)增加新节点NodeName
* @param parent 要添加子节点的节点的节点名
* @param NodeName 子节点
* @param addall 是否添加所有parent节点
* @roseuid 3ECB40D10250
*/
public void addNode(String parent, Node NodeName,
boolean addall);
/**
* 在所有parent节点或指定的parent节点处(具体位置由setMarkSign(),
* setMark()或setMarkAdv()来确定)删除名为
* NodeName的attribute和子节点
* @param parent 要删除子节点或attribute的节点的节点名
* @param NodeName 要删除的子节点名或attribute名
* @param delall 是否删除所有的NodeName子节点和attribute
*/
public void delNode(String parent,String
NodeName,boolean delall);

/**
* 在所有parent节点或指定的parent节点处(具体位置由setMarkSign(),
* setMark()或setMarkAdv()来确定)
* 把NodeOld的节点替换为NodeNew
* @param parent 要操作的节点的节点名
* @param NodeOld 要替换的节点的节点名
* @param NodeNew 替换成的节点
* @param editAll 是否替换所有的parent的子节点NodeOld到NodeNew
*/
public void editNode(String parent,String NodeOld,
Node NodeNew,boolean editAll);


/**
* 设定xml文档数据的位置(根据数据的坐标位置)
* @param index 坐标
* @return boolean
* @roseuid 3ECB427B0357
*/
public boolean setMark(int index);

/**
* 设定xml文档数据的位置(根据数据的值)
* @param name attribute名,如果为空,就查询节点的值
* @param value 要查询的attribute的值或节点的值
* @return boolean
* @roseuid 3ECB42BB03A9
*/
public boolean setMark(String name,String value);

/**
* 设定setMark()方法所依据的节点名.
* @param NodeName 节点名
* @roseuid 3ECB43820157
*/
public void setMarkSign(String NodeName);

/**
* 设定xml文档数据的位置(根据数据的值,复杂查询)
* @param name attribute名列表,如果为空,就查询节点的值
* @param value 要查询的attribute的值或节点的值的列表
* @param Operation 操作算法。 (在XMLToolTest子类中
* 默认为 \"and\",只有\"and\"和\"or\"两种操作)
* @return boolean
*/
public boolean setMarkAdv(String[] name,String[] value,
String operation);
/**
* 创建一个空的document.象
* @return document. */
public document.nbspCreatedocument.);
/**
* 创建一个空的名为name的Element对象
* @param name Element名
* @return Element
*/
public Element CreateElement(String name);
/**
* 创建一个空的名为name的Comment对象
* @param name Comment名
* @return Comment
*/
public Comment CreateComment(String name);
/**
* 创建一个空的名为name的Text对象
* @param name Text名
* @return Text
*/
public Text CreateText(String name);
/**
* 创建一个空的名为name的Attr对象
* @param name Attr名
* @return Attr
*/
public Attr CreateAttr(String name);
/**
* 根据操作过的document.XMLTool类的内部
* document.)生成xml文件.
* @param path xml文件位置
*/
public void Output(String path);
/**
* 根据操作过的document.XMLTool类的内部document.)
* 把build()方法指定的xml文件重写.
*/
public void Output();
/**
* 设定生成xml文件的编码
* @param encod 编码,如: \"UTF8\" \"GBK\"
*/
public void setEncoding(String encod);
/**
* 根据指定的Node对象生成xml文件.
* @param path xml文件位置
* @param docu 指定的Node对象
*/
public void Output(String path,Node docu);
/**
* 根据指定的Node对象生成xml文件.
* @param path xml文件位置
* @param docu 指定的Node对象
* @param noTop 是否去掉头尾节点名。如去掉
* 或去掉最上层
* 和
*/
public void Output(String path,Node docu,boolean noTop);
/**
* 根据指定的Node节点名生成xml文件.
* @param path xml文件位置
* @param NodeName 指定的Node节点名
* @param noTop 是否去掉头尾节点名。如去掉
* 或去掉
* 最上层 和
*/
public void Output(String path,String NodeName,
boolean noTop);
/**
* 根据指定的Node节点名生成xml文件.
* @param path xml文件位置
* @param NodeName 指定的Node节点名
* @param indexs NodeName节点的位置
* @param noTop 是否去掉头尾节点名。如去掉
* 或去掉最上层
* 和
*/
public void Output(String path,String NodeName,
int indexs,boolean noTop);
/**
* 设定生成xml文件时自动添加换行和空格.(如果Docment是
* 由xml文件生成的,一般已经有空格和换行的空节点)
* 就不用在去添加空格和换行)
*/
public void isEnableMakeUp();
/**
* 设定生成xml文件时不自动添加换行和空格.(如果Docment是
* 由xml文件生成的,一般已经有空格和换行的空节点)
* 就不用在去添加空格和换行),默认为这种情况。
* 主要用与XMLTool处理多次xml文档时的开关。
*/
public void isNotEnableMakeUp();
/**
* 获得当前做标记的节点名
* @return String
*/
public String getCurrentNodeName();
/**
* 获得当前做标记的节点名的位置编号。
* @return int
*/
public int getIndex();
/**
* 获得当前XMLTool中的document.
* @return document. */
public document.nbspgetdocument.ource();
/**
* 设定写xml文件时xml的头
*/
public void setHeader(String Header);