上一篇主要是贴了几种节点的代码,还有一个类Attribute代表属性,键值对的形式。直接贴代码:
/*
* 形如 btnEDate="2014-12-15"
* */
public class Attribute implements Serializable{
private static final long serialVersionUID = 4233216982243098384L;
private String attributeName;
private String attributeValue = "";
public Attribute(){}
public Attribute(String attributeName,String attributeValue){
if(attributeName==null||attributeName.trim().equals("")){
DocumentUtil.throwException(DocumentUtil.ARGUMENT_NULL);
}
this.attributeName = attributeName.trim();
this.attributeValue = attributeValue==null?"":attributeValue;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(attributeName);
sb.append("=\"");
sb.append(attributeValue);
sb.append("\"");
return sb.toString();
}
public String getAttributeName() {
return attributeName;
}
public void setAttributeName(String attributeName) {
if(attributeName==null||attributeName.trim().equals("")){
DocumentUtil.throwException(DocumentUtil.ARGUMENT_NULL);
}
this.attributeName = attributeName.trim();
}
public String getAttributeValue() {
return attributeValue;
}
public void setAttributeValue(String attributeValue) {
if(attributeValue==null){
DocumentUtil.throwException("空指针!");
}
this.attributeValue = attributeValue;
}
@Override
public boolean equals(Object obj) {
if(this==obj){
return true;
}
try{
Attribute att = (Attribute)obj;
return attributeName.equals(att.attributeName);
}catch(Exception e){
return false;
}
}
}
下面就是写document类了,因为需要的“材料”都准备好了。
/** xml文档对象 */
public class Document implements Serializable {
/**
* 序列化版本号
*/
private static final long serialVersionUID = 1353311427641889804L;
/*
* <?xml version="1.0" encoding="UTF-8"?>
*/
public final static String DEFAULT_VERSION = "1.0";
public final static String UTF8 = "UTF-8";
public final static String DEFAULT_ENCODING = UTF8;
/** 版本号 */
private String version = DEFAULT_VERSION;
/** 编码 */
private String encoding = DEFAULT_ENCODING;
public final static String GBK = "gbk";
public final static String GB2312 = "gb2312";
public final static String ISO8859_1 = "ISO8859-1";
/**文档属性换行*/
public static final int NEW_LINE = 0x0;
/**文档属性不换行*/
public static final int SINGLE_LINE = 0x1;
/**
* 文档属性是否换行(格式化用)
* */
public int attributeLine = SINGLE_LINE;
/** 子节点列表,其中有且只有一个根节点,可能还有注释节点 */
private List<Node> nodeList = new ArrayList<Node>();
/**
* 类似<?xml version="1.0" encoding="utf-8" standalone="no"?>,可能还有其他内容
* */
private final List<Attribute> headAttributeList = new ArrayList<Attribute>();
public Document() {
init();
}
private void init() {
headAttributeList.add(new Attribute("version", DEFAULT_VERSION));
headAttributeList.add(new Attribute("encoding", DEFAULT_ENCODING));
}
public void addAttribute(Attribute attribute){
if(attribute==null){
return;
}
int flag = 0;
for(int i=0;i<headAttributeList.size();i++){
Attribute att = headAttributeList.get(i);
if(att.equals(attribute)){
headAttributeList.remove(i);
headAttributeList.add(i, attribute);
flag++;
break;
}
}
if(flag == 0){
headAttributeList.add(attribute);
}
if(attribute.getAttributeName().equalsIgnoreCase("encoding")){
encoding = attribute.getAttributeValue();
}
}
public void setVersion(String version) {
if (version == null || ((version = version.trim()).equals(""))) {
version = DEFAULT_VERSION;
}
this.version = version;
addAttribute(new Attribute("version", this.version));
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding == null
|| (encoding = encoding.trim()).length() == 0 ? DEFAULT_ENCODING
: encoding.trim();
addAttribute(new Attribute("encoding", this.encoding));
}
public List<Node> getNodeList() {
return nodeList;
}
/** 设置节点list*/
public void setNodeList(List<Node> nodeList) {
if (nodeList == null || nodeList.size() == 0) {
DocumentUtil.throwException("参数不能为空!");
}
int flag = 0;
for (Node node : nodeList) {
if(node instanceof TextNode){
DocumentUtil.throwException("文档对象不能包含文本节点!");
}
if (node instanceof Element) {
flag++;
}
}
if (flag != 1) {
DocumentUtil.throwException("只能有且只有一个根节点!");
}
this.nodeList = nodeList;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
try {
Document document = (Document) obj;
return version.equalsIgnoreCase(document.version)
&& encoding.equalsIgnoreCase(document.encoding)
&& nodeList.equals(document.nodeList);
} catch (Exception e) {
return false;
}
}
public Element getRootNode() {
if (nodeList == null || nodeList.size() == 0) {
return null;
}
for (Node node : nodeList) {
if (node != null && node instanceof Element) {
return (Element) node;
}
}
return null;
}
/**
* 设置根节点
* */
public boolean setRootNode(Element root) {
if (root == null) {
return false;
}
root.domFather = this;
if (hasSetRootNode()) {
for (int i = 0; i < nodeList.size(); i++) {
Node node = nodeList.get(i);
if (node != null && node instanceof Element) {
nodeList.remove(i);
nodeList.add(i, root);
node.domFather = null;
return true;
}
}
}
return nodeList.add(root);
}
/**
* 设置根节点
* */
public boolean setRootNode(Element root, int index) {
if (root == null) {
return false;
}
root.domFather = this;
if (hasSetRootNode()) {
for (int i = 0; i < nodeList.size(); i++) {
Node node = nodeList.get(i);
if (node != null && node instanceof Element) {
nodeList.remove(i);
nodeList.add(index, root);
node.domFather = null;
return true;
}
}
}
nodeList.add(index, root);
return true;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
if(headAttributeList!=null&&headAttributeList.size()>0){
sb.append("<?xml");
if(attributeLine == SINGLE_LINE){
for(int i=0;i<headAttributeList.size();i++){
Attribute attribute = headAttributeList.get(i);
sb.append(" "+attribute.toString());
}
}else if(attributeLine == NEW_LINE){
for(int i=0;i<headAttributeList.size();i++){
Attribute attribute = headAttributeList.get(i);
if(i==0){
sb.append(" "+attribute.toString());
}else{
sb.append("\n"+" "+attribute.toString());
}
}
}
sb.append("?>");
}
for (Node node : nodeList) {
sb.append("\n");
sb.append(node.toString());
}
return sb.toString();
}
public boolean addNode(Node node) {
if (node == null) {
return false;
}
if(node instanceof TextNode){
DocumentUtil.throwException("文档不能添加文本节点!");
}
if (node instanceof AnnotationNode) {
node.domFather = this;
return nodeList.add(node);
} else {
Element element = (Element) node;
return setRootNode(element);
}
}
public boolean hasSetRootNode() {
return getRootNode() != null;
}
/**
* 保存到文件
* */
public void saveTo(File file) throws IOException {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), encoding));
writer.write(toString());
if(writer!=null){
writer.flush();
writer.close();
writer = null;
}
}
/**
* 保存到文件
* */
public void saveTo(String filename) throws IOException{
saveTo(new File(filename));
}
public List<Attribute> getHeadAttributeList() {
return headAttributeList;
}
/**
* 文档格式化
* */
public void setRootNodeAttributeLine(boolean singleLine){
Element root = getRootNode();
if(root!=null){
root.setAll_attributeLine(singleLine);
}
}
/**
* 移除节点
* */
public boolean remove(Node node){
DocumentUtil.throwExceptionIfNull(node);
if(nodeList==null||nodeList.size()==0){
DocumentUtil.throwException(new RuntimeException("空指针!"));
}
if(nodeList.remove(node)){
node.domFather = null;
return true;
}
return false;
}
/**
* 得到第一个子节点
* */
public Node getFirstChild(){
if(nodeList==null||nodeList.isEmpty()){
return null;
}
return nodeList.get(0);
}
/**
* 得到最后一个子节点
* */
public Node getLastChild(){
if(nodeList==null||nodeList.isEmpty()){
return null;
}
return nodeList.get(nodeList.size()-1);
}
}
这个类主要是对document对象的操作。 操作完了就可以把document对象保存到xml文件,saveTo方法就是做这个的。总的来说创建文档以及对文档的写操作都不难。主要是建好数据模型。有了思路所以编程就很简单了。最复杂的是她的逆向需求,即读取xml文件解析得到document文档对象。见下一篇