JAVA语言设计一个简单的XML文档生成器
最近做了一个公司的笔试题,使用Java语言设计一个简单xml文档生成器,自己尝试写了一遍。
题目
1、设计一个简单的XML文档生成器,它满足以下功能:
1)节点能够添加或者删除其它子节点, 操作同时要保证每个节点只能有一个父节点, 一个节点只能从属于一个父节点;
2) 节点能够获取父节点对象;节点能够获取所有子节点对象。
3)节点有添加或者读取XML属性的操作;
4)当前节点有方法能打印当前节点和所有子节点(包括子孙节点)的内容。
5)XML的encoding方式能够设置,如:

要求:
1)用java写出完整程序;
2)主程序测试生成器,它构建下面文档,然后打印出来。

代码实现
1、先创建一个循环队列,后面层次遍历树结构使用。
/**
* 循环队列
*/
public class MyQueue {
/**
* 初始化大小
*/
private final int SIZE = 20;
/**
* 数据
*/
private Object[] queArray;
/**
* 队头
*/
private int front;
/**
* 队尾
*/
private int rear;
public MyQueue(){
queArray = new Object[SIZE];
front = 0;
rear = -1;
}
/**
* 入队
* @param o
*/
public void insert(Object o){
if (rear == SIZE - 1){
rear = -1;
}
queArray[++rear] = o;
}
/**
* 出队
* @return
*/
public Object remove(){
Object temp = queArray[front++];
if (front == SIZE){
front = 0;
}
return temp;
}
/**
* 判空
* @return
*/
public boolean isEmpty(){
return (rear + 1 == front || front + SIZE - 1 == rear);
}
}2、创建节点类。
package com.zsc.xml;
import lombok.*;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
/**
* xml节点
*/
@Setter
@Getter
@Accessors(chain = true)
public class Node {
/**
* 节点名称
*/
private String name;
/**
* 节点Id
*/
private String id;
/**
* 节点描述
*/
private String description;
/**
* 子节点
*/
private List<Node> childNodes = new ArrayList<>();
/**
* 父节点
*/
private Node parentNode;
/**
* 添加子节点
* @param childNode
*/
public void setChildNode(Node childNode){
if (childNode.getParentNode() == null){
throw new RuntimeException("加入的子节点不存在父节点,设置失败!");
}
List<Node> nodes = childNode.getParentNode().getChildNodes();
if (!nodes.isEmpty()){
Optional<Node> optional = nodes.stream().filter(n -> n.getName().equals(childNode.getName())).findFirst();
if (optional.isPresent()){
throw new RuntimeException("父节点" + childNode.getParentNode().getName() + "已存在" + optional.get().getName() +"节点了,添加失败!");
}
}
nodes.add(childNode);
childNode.getParentNode().setChildNodes(nodes);
}
/**
* 查找到顶端节点
* @return
*/
public Node findParentNode(){
Node parentTemp = parentNode == null ? this : parentNode;
while (parentTemp.getParentNode() != null){
parentTemp = parentTemp.getParentNode();
}
return parentTemp;
}
/**
* 层次遍历xml树结构
* 如果传入的参数不为null,则遍历当前节点有方法能打印当前节点和所有子节点(包括子孙节点)的内容
* @param n
*/
public void printNodeInfo(Node n){
Node root = null;
if (n != null){
root = n;
}else {
//获取顶端root节点
root = findParentNode();
}
MyQueue queue = new MyQueue();
//根节点先被访问,入队
queue.insert(root);
while (!queue.isEmpty()){
Node temp = (Node) queue.remove();
System.out.println(temp.getName() + "--------->" +(temp.getParentNode() == null? "不存在父节点":"父节点为:" + temp.getParentNode().getName()));
List<Node> nodes = temp.getChildNodes();
if (!nodes.isEmpty()){
for (Node node : nodes) {
//入队
queue.insert(node);
}
}
}
}
/**
* 递归删除关联节点
* @param node
*/
public static void removeNode(Node node){
//该节点的子节点
List<Node> nodes = node.getChildNodes();
if (!nodes.isEmpty()){
List<Node> tempNodes = new ArrayList<>(nodes);
for (Node n : tempNodes) {
removeNode(n);
}
}
//移除对应的父节点里面的子节点
Node parentNode = node.getParentNode();
if (parentNode != null){
List<Node> childNodes = parentNode.getChildNodes();
childNodes.remove(node);
node.getParentNode().setChildNodes(childNodes);
}
node.setParentNode(null);
}
/**
* 递归构建xml文件格式
* @return
*/
public static String createXml(Node node){
StringBuilder builder = new StringBuilder();
if (!StringUtils.isEmpty(node.getName())){
builder.append("<").append(node.getName());
if (!StringUtils.isEmpty(node.getId())){
builder.append(" ID=\"").append(node.getId()).append("\"");
}
builder.append(">").append("\r\n");
if (!StringUtils.isEmpty(node.getDescription())){
builder.append(node.getDescription()).append("\r\n");
}
//获取该节点的子节点
List<Node> childNodes = node.getChildNodes();
if (!childNodes.isEmpty()){
for (Node childNode : childNodes) {
//递归调用
builder.append(createXml(childNode));
}
}
builder.append("</").append(node.getName()).append(">").append("\r\n");
}
return builder.toString();
}
}3、创建XmlBuilder类。
package com.zsc.xml;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
/**
* XML生成
*/
@Setter
@Getter
public class XMLBuilder {
/**
* 版本
*/
private String version;
/**
* 编码
*/
private String encoding;
/**
* 生成头文件
* @param version
* @param encoding
* @return
*/
public String createXmlHeader(String version,String encoding){
if (StringUtils.isEmpty(version)) return "";
if (StringUtils.isEmpty(encoding)) return "";
this.version = version;
this.encoding = encoding;
StringBuilder builder = new StringBuilder();
builder.append("<?xml version=\"").append(this.version).append("\"")
.append(" encoding=\"").append(this.encoding).append("\"?>")
.append("\r\n");
return builder.toString();
}
/**
* 打印xml结构
* @param node
*/
public void printXmlInfo(String version,String encoding,Node node){
String xml = this.createXmlHeader(version, encoding) + Node.createXml(node);
System.out.println(xml);
}
public static void main(String[] args) {
Node root = new Node();
root.setId("").setName("CategoryList").setDescription("");
Node node1 = new Node();
node1.setParentNode(root).setName("Category").setId("01").setDescription("");
root.setChildNode(node1);
Node node2 = new Node();
node2.setParentNode(node1).setName("MainCategory").setId("").setDescription("XML");
node1.setChildNode(node2);
Node node3 = new Node();
node3.setParentNode(node1).setName("Description").setId("").setDescription("This is a list my XML articles.");
node1.setChildNode(node3);
Node node4 = new Node();
node4.setParentNode(node1).setName("Active").setId("").setDescription("true");
node1.setChildNode(node4);
// Node node5 = new Node();
// node5.setParentNode(node4).setId("01").setName("test").setDescription("test");
// node4.setChildNode(node5);
// Node.removeNode(node1);
//
// root.printNodeInfo(null);
// System.out.println(Node.createXml(root));
XMLBuilder xmlBuilder = new XMLBuilder();
xmlBuilder.printXmlInfo("1.0","UTF-8",root);
System.out.println("-----------------------------删除MainCategory节点后------------------------------------------------------");
Node.removeNode(node2);
xmlBuilder.printXmlInfo("1.0","UTF-8",root);
System.out.println("-----------------------------删除Category节点后------------------------------------------------------");
Node.removeNode(node1);
xmlBuilder.printXmlInfo("1.0","UTF-8",root);
}
}
















