如 第一篇,节点分3种类型。代码贴出来:
1、 先是注释节点类AnnotationNode:
/**
* 注释节点
*
* @形如<!-- xxxx -->
* */
public class AnnotationNode extends Node {
private static final long serialVersionUID = -8705251712083166809L;
/** 注释内容 */
private String annotation;
public AnnotationNode() {
annotation = "";
}
public AnnotationNode(String annotation) {
if (annotation == null) {
this.annotation = "";
} else {
this.annotation = annotation;
}
}
public String getAnnotation() {
return annotation;
}
public void setAnnotation(String annotation) {
this.annotation = annotation == null ? "" : annotation;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(printSpace());
sb.append("<!--");
sb.append(annotation);
sb.append("-->");
return sb.toString();
}
}
因为注释节点没有子节点,所以代码很简单了。toString()方法里面用到了printSpace()方法,这是为文档美化加上去的。因为打印文档对象,或把文档对象保存进文件的时候需要格式化增加可读性。
2、文本节点类TextNode:
/**
* 文本节点,纯字符串
* */
public class TextNode extends Node {
private static final long serialVersionUID = 4992529597680776751L;
/**
* 节点内容
* */
private String text;
public String getText() {
return text;
}
public void setText(String text) {
if (text != null) {
if (text.indexOf("<") >= 0) {
DocumentUtil.throwException("非法格式!");
}
}
this.text = text;
}
public TextNode() {
}
public TextNode(String text) {
setText(text);
}
@Override
public String printSpace(){
return super.printSpace();
}
@Override
public String toString() {
if (text == null) {
return "";
}
StringBuffer sb = new StringBuffer();
String space = printSpace();
if (text != null && text.length() > 0) {
sb.append(space);
sb.append(text);
}
return sb.toString();
}
}
3、最复杂的是普通节点类Element:
/**
* 普通节点
* */
public class Element extends Node implements INodeAction {
private static final long serialVersionUID = 8400116833587665357L;
/**
* 属性列表
* */
private List<Attribute> attributeList = new ArrayList<Attribute>();
/**
* 子节点列表
* */
private final List<Node> nodeList = new ArrayList<Node>();
/** 节点名 */
private String name;
/** 节点属性换行 */
public static final int NEW_LINE = 0x0;
/** 节点属性不换行 */
public static final int SINGLE_LINE = 0x1;
/**
* 节点属性是否换行(格式化用)
* */
public int attributeLine = SINGLE_LINE;
/** 设置自己以及所有的后代节点是否换行,true则不换行,false换行 */
public void setAll_attributeLine(boolean singleLine) {
attributeLine = singleLine ? SINGLE_LINE : NEW_LINE;
Set<Node> nodes = getChildNodes();
for (Iterator<Node> it = nodes.iterator(); it.hasNext();) {
Node node = it.next();
if (node instanceof Element) {
((Element) node).attributeLine = attributeLine;
}
}
}
public List<Attribute> getAttributeList() {
return attributeList;
}
public void clearAllAttribute() {
attributeList.clear();
}
public void addAttribute(Attribute attribute) {
if (attribute == null) {
return;
}
int flag = 0;
for (int i = 0; i < attributeList.size(); i++) {
Attribute att = attributeList.get(i);
if (att.equals(attribute)) {
attributeList.remove(i);
attributeList.add(i, attribute);
flag++;
break;
}
}
if (flag == 0) {
attributeList.add(attribute);
}
}
public void deleteAttributeByAttributeName(String attributeName) {
for (Attribute att : attributeList) {
if (att.getAttributeName().equals(attributeName)) {
attributeList.remove(att);
return;
}
}
}
public void addAttributes(List<Attribute> list) {
if (list != null) {
for (Attribute attribute : list) {
addAttribute(attribute);
}
}
}
public void setAttributes(List<Attribute> list) {
attributeList = list;
}
public boolean containsAttribute(Attribute attribute) {
for (Attribute att : attributeList) {
if (att.equals(attribute)
&& att.getAttributeValue().equals(
attribute.getAttributeValue())) {
return true;
}
}
return false;
}
public List<Node> getNodeList() {
return nodeList;
}
/**
* 添加子节点
* */
public void addSonNode(Node node) {
DocumentUtil.throwExceptionIfNull(node);
if (nodeList.add(node)) {
node.father = this;
}
}
/**
* 删除子节点
* */
public void deleteSonNode(Node node) {
if (nodeList.remove(node)) {
node.father = null;
}
}
/** 查询本节点以及其后代节点中名称为name的所有节点 */
public Set<Node> getNodesByName(String name) {
Set<Node> set = getChildNodes();
set.add(this);
Set<Node> s = new HashSet<Node>();
Iterator<Node> it = set.iterator();
for (; it.hasNext();) {
Node node = it.next();
if (!(node instanceof Element)) {
continue;
}
Element element = (Element) node;
if (element.name.equals(name)) {
s.add(node);
}
}
return s;
}
/**
* 得到本节点的所有后代节点
* */
public Set<Node> getChildNodes() {
Set<Node> set = new HashSet<Node>();
Element node = this;
if (node.nodeList.size() > 0) {
for (Node n : node.nodeList) {
set.add(n);
if (n instanceof Element) {
Element element = (Element) n;
set.addAll(element.getChildNodes());
}
}
}
return set;
}
public String getName() {
return name;
}
public void setName(String name) {
DocumentUtil.throwExceptionIfNull(name);
this.name = name;
}
/*
* 考虑两种形式: <Adv subDirectory="" Img="02.png"/>
*
* <adv subDirectory="" Img="02.png"> ... </adv>
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
String space = printSpace();
// 用递归实现
sb.append(space);
sb.append("<");
sb.append(name);
for (int i = 0; i < attributeList.size(); i++) {
Attribute attribute = attributeList.get(i);
if (i == 0) {
sb.append(" " + attribute.toString());
} else {
sb.append(attributeLine == SINGLE_LINE ? " "
+ attribute.toString() : "\n" + space + " "
+ attribute.toString());
}
}
if (nodeList.size() == 0) {
sb.append("/>");
return sb.toString();
}
sb.append(">");
for (Node node : nodeList) {
sb.append("\n");
sb.append(node.toString());
}
sb.append("\n");
sb.append(space);
sb.append("</" + name + ">");
return sb.toString();
}
/** 获取第一个子节点,如果没有则返回null */
public Node getFirstChildNode() {
return nodeList.isEmpty() ? null : nodeList.get(0);
}
/** 获取最后一个子节点,如果没有则返回null */
public Node getLastChildNode() {
return nodeList.isEmpty() ? null : nodeList.get(nodeList.size() - 1);
}
/** 获取根节点 */
public Element getRootNode() {
if (father == null) {
if (domFather == null) {
DocumentUtil.throwException("节点还没有添加到文档对象!");
}else{
return this;
}
}
Element node = this;
while(node.father!=null){
node = node.father;
if(node.father==null){
if (node.domFather == null) {
DocumentUtil.throwException("节点还没有添加到文档对象!");
}else{
return node;
}
}
}
return null;
}
}
普通节点稍复杂,主要是包含子节点以及属性。子节点为nodeList ,属性为attributeList 。这样在其中增加子节点或属性都不难。对节点的增删改查都很方便。比较复杂一点的是toString()方法 ,也就是把节点写成xml字符串的格式。用递归实现简单一点。查找子节点也用到了递归方法,递归在这里挺常用。
对于getChildNodes()这个方法,是得到后代节点。用“后代节点”这个词是为了区分子节点,把节点A的子节点以及子节点的子节点(依次类推)统归到节点A的后代节点。这样很方便对节点对象的操作。
下面就写文档类document了,见下一篇。