如 第一篇,节点分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了,见下一篇。
原文链接:/xml/299357.html