今天我们来聊聊基于DOM方式实现解析和生成XML文档
一般web开发的xnl文档:
1、DOM方式解析XML文档
<?xml version="1.0" encoding="UTF-8"?>
<accounts>
<!-- 定义age属性 -->
<account age="20" bankNo="10001">
<id>610500199909022342</id>
<name>张三</name>
<money>5000.0</money>
</account>
<account age="21" bankNo="10002">
<id>610500199709022342</id>
<name>李四</name>
<money>4500.0</money>
</account>
</accounts>
实体类:
package com.yueqian.xml;
/**
* 封装xml的实体类
* @author LinChi
*
*/
public class Account {
private String bankNo;
private int age;
private String id;
private String name;
private double money;
public Account() {
super();
}
public Account(String bankNo, int age, String id, String name, double money) {
super();
this.bankNo = bankNo;
this.age = age;
this.id = id;
this.name = name;
this.money = money;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public String getBankNo() {
return bankNo;
}
public void setBankNo(String bankNo) {
this.bankNo = bankNo;
}
@Override
public String toString() {
return this.bankNo+"|"+this.age+"|"+this.id+"|"+this.name+"|"+this.money;
}
}
解析:
/**
* 解析xml文档
* @param filePath
* @return
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
*/
public static List<Account> readXml(String filePath) throws ParserConfigurationException, SAXException, IOException{
//过滤非法
if(filePath == null || filePath.length()<=0) {
System.out.println("ERROR: filePath args is null!");
//返回null列表
return Collections.EMPTY_LIST;
}
//创建文件
File xmlFile = new File(filePath);
//判断文件是否存在
if(!xmlFile.exists()) {
System.out.println("ERROR: filePath not exists!");
//返回null列表
return Collections.EMPTY_LIST;
}
//读取xml文件到列表
List<Account> xmlList = new ArrayList<Account>();
//获取DOM构建器的工厂对象
DocumentBuilderFactory bf = DocumentBuilderFactory.newInstance();
//通过工厂对象创建DOM构建器
DocumentBuilder build = bf.newDocumentBuilder();
//通过构建器对xml进行解析,获得Document对象节点
Document doc = build.parse(xmlFile);
//获得根节点
Element rootEle = doc.getDocumentElement();
//输出跟标签
// System.out.println(rootEle.getTagName());
//获取根标签下的所有子标签
NodeList accNodeList = rootEle.getChildNodes();
//遍历输出每个account标签
for(int i = 0;i<accNodeList.getLength();i++) {
//获取指定位置下的account节点
Node node = accNodeList.item(i);
//输出每个节点的名称
// System.out.println(node.getNodeName());
//跳过无用的文本信息构成的Node,即不是Element的节点
if(!(node instanceof Element) ) {
continue;
}
//将节点对象 Node转换为元素对象 Element
Element accEle = (Element)node;
//构造一个新的账户对象
Account acc = new Account();
//获取属性
String ageAttr = null;
String bankNo = null;
//获得accEle上的所有属性
NamedNodeMap accAttrs = accEle.getAttributes();
//循环遍历所有属性值
for(int j = 0;j<accAttrs.getLength();j++) {
//循环遍历指定位置下的所有属性
Node attrNode = accAttrs.item(j);
//将attrNode 转换为 Attr属性
Attr attr = (Attr)attrNode;
//判断属性信息
if("age".equals(attr.getNodeName())) {
ageAttr = attr.getNodeValue();
}
if("bankNo".equals(attr.getNodeName())) {
bankNo = attr.getNodeValue();
}
}
System.out.println();
int age = 0;
//转换age为数值
try {
age = Integer.parseInt(ageAttr.trim());
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//设置年龄属性
acc.setAge(age);
//设置银行账户属性
acc.setBankNo(bankNo);
//获取子标签 account标签的属性标签
for(int k = 0;k<accEle.getChildNodes().getLength();k++) {
Node subNode = accEle.getChildNodes().item(k);
if(!(subNode instanceof Element) ) {
continue;
}
//讲属性标签节点转换为Element
Element accField = (Element)subNode;
//判断是否为name标签
if("name".equals(accField.getNodeName())) {
//设置姓名属性 标签元素之间的元素用Element对象.getTextContent()
acc.setName(accField.getTextContent());
}
//判断是否为id标签
if("id".equals(accField.getNodeName())) {
//设置姓名属性 标签元素之间的元素用Element对象.getTextContent()
acc.setId(accField.getTextContent());
}
//判断是否为name标签
if("money".equals(accField.getNodeName())) {
double money = 0;
try {
money = Double.parseDouble(accField.getTextContent());
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (DOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//设置姓名属性 标签元素之间的元素用Element对象.getTextContent()
acc.setMoney(money);
}
}
//添加对象到列表
xmlList.add(acc);
}
return xmlList;
}
测试:
public static void main(String[] args) {
try {
List<Account> list = readXml("xml/Test.xml");
System.out.println(list);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
成果截图:
2、DOM方式生成XML文档
生成:
/**
* 生成xml文档
* @param path 文件路径
* @param fileName 文件名称
* @param data 集合列表
* @return
* @throws ParserConfigurationException
* @throws TransformerException
*/
public static boolean writeXml(String path,String fileName,List<Account> data) throws ParserConfigurationException, TransformerException{
//非法操作
if(path == null || path.length()<=0 ||
fileName == null || fileName.length()<=0 ||
data == null || data.size()<=0) {
System.out.println("ERROR: filePath args is null!");
//返回null列表
return false;
}
File dir = new File(path);
//判断文件是否存在,不存在则创建
if(!dir.exists()) {
dir.mkdirs();
}
//检测文件是否存在
File xmlFile = new File(dir, fileName);
//获取DOM工厂对象
DocumentBuilderFactory bf = DocumentBuilderFactory.newInstance();
//根据工厂对象创建构建者
DocumentBuilder build = bf.newDocumentBuilder();
//根据构建者创建DOM文档树
Document doc = build.newDocument();
//建立根节点
Element rootEle = doc.createElement("accounts");
//将根节点添加到文档树中
doc.appendChild(rootEle);
//循环Account对象列表,构造account的xml表示
for(Account acc:data) {
//构造account节点
Element accEle = doc.createElement("account");
//为account节点设置其属性
accEle.setAttribute("age", String.valueOf(acc.getAge()));
accEle.setAttribute("bankNo", acc.getBankNo());
//添加account节点到accounts上
rootEle.appendChild(accEle);
//添加id子标签
Element idEle = createSubElement(doc,"id",acc.getId());
//添加id节点到account节点
accEle.appendChild(idEle);
//添加name子标签
Element nameEle = createSubElement(doc,"name",acc.getName());
//添加id节点到account节点
accEle.appendChild(nameEle);
//添加money子标签
Element moneyEle = createSubElement(doc,"money",String.valueOf(acc.getMoney()));
//添加id节点到account节点
accEle.appendChild(moneyEle);
}
//将添加的树状结构写入到doc
TransformerFactory factory = TransformerFactory.newInstance();
Transformer tf = factory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(xmlFile);
tf.transform(source, result);
return true;
}
/**
* 建立一个含有简单文本内容的Element对象
* @param doc
* @param tagName
* @param textContext
* @return
*/
private static Element createSubElement(Document doc,String tagName,String textContext) {
//创建Element对象
Element element = doc.createElement(tagName);
//添加文本内容,文本内容需要添加到TextNode节点
Text text = doc.createTextNode(textContext);
//添加文本内容到标签
element.appendChild(text);
return element;
}
测试:
//写xml文件
public static void main(String[] args) {
List<Account> accList = new ArrayList<Account>();
accList.add(new Account("acc1003", 25, "610105200210102233" ,"小王", 6000.0));
try {
System.out.println(writeXml("I:/","accs.xml",accList));
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
成果截图:
true
DOM读写XML全部代码:
package com.yueqian.xml;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
import org.xml.sax.XMLFilter;
/**
* DOM方式读写xml文件工具类
* @author LinChi
*
*/
public class TestXml {
public static void main(String[] args) {
try {
List<Account> list = readXml("xml/Test.xml");
System.out.println(list);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//写xml文件
List<Account> accList = new ArrayList<Account>();
accList.add(new Account("acc1003", 25, "610105200210102233" ,"小王", 6000.0));
try {
System.out.println(writeXml("I:/","accs.xml",accList));
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 解析xml文档
* @param filePath
* @return
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
*/
public static List<Account> readXml(String filePath) throws ParserConfigurationException, SAXException, IOException{
//过滤非法
if(filePath == null || filePath.length()<=0) {
System.out.println("ERROR: filePath args is null!");
//返回null列表
return Collections.EMPTY_LIST;
}
//创建文件
File xmlFile = new File(filePath);
//判断文件是否存在
if(!xmlFile.exists()) {
System.out.println("ERROR: filePath not exists!");
//返回null列表
return Collections.EMPTY_LIST;
}
//读取xml文件到列表
List<Account> xmlList = new ArrayList<Account>();
//获取DOM构建器的工厂对象
DocumentBuilderFactory bf = DocumentBuilderFactory.newInstance();
//通过工厂对象创建DOM构建器
DocumentBuilder build = bf.newDocumentBuilder();
//通过构建器对xml进行解析,获得Document对象节点
Document doc = build.parse(xmlFile);
//获得根节点
Element rootEle = doc.getDocumentElement();
//输出跟标签
// System.out.println(rootEle.getTagName());
//获取根标签下的所有子标签
NodeList accNodeList = rootEle.getChildNodes();
//遍历输出每个account标签
for(int i = 0;i<accNodeList.getLength();i++) {
//获取指定位置下的account节点
Node node = accNodeList.item(i);
//输出每个节点的名称
// System.out.println(node.getNodeName());
//跳过无用的文本信息构成的Node,即不是Element的节点
if(!(node instanceof Element) ) {
continue;
}
//将节点对象 Node转换为元素对象 Element
Element accEle = (Element)node;
//构造一个新的账户对象
Account acc = new Account();
//获取属性
String ageAttr = null;
String bankNo = null;
//获得accEle上的所有属性
NamedNodeMap accAttrs = accEle.getAttributes();
//循环遍历所有属性值
for(int j = 0;j<accAttrs.getLength();j++) {
//循环遍历指定位置下的所有属性
Node attrNode = accAttrs.item(j);
//将attrNode 转换为 Attr属性
Attr attr = (Attr)attrNode;
//判断属性信息
if("age".equals(attr.getNodeName())) {
ageAttr = attr.getNodeValue();
}
if("bankNo".equals(attr.getNodeName())) {
bankNo = attr.getNodeValue();
}
}
System.out.println();
int age = 0;
//转换age为数值
try {
age = Integer.parseInt(ageAttr.trim());
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//设置年龄属性
acc.setAge(age);
//设置银行账户属性
acc.setBankNo(bankNo);
//获取子标签 account标签的属性标签
for(int k = 0;k<accEle.getChildNodes().getLength();k++) {
Node subNode = accEle.getChildNodes().item(k);
if(!(subNode instanceof Element) ) {
continue;
}
//讲属性标签节点转换为Element
Element accField = (Element)subNode;
//判断是否为name标签
if("name".equals(accField.getNodeName())) {
//设置姓名属性 标签元素之间的元素用Element对象.getTextContent()
acc.setName(accField.getTextContent());
}
//判断是否为id标签
if("id".equals(accField.getNodeName())) {
//设置姓名属性 标签元素之间的元素用Element对象.getTextContent()
acc.setId(accField.getTextContent());
}
//判断是否为name标签
if("money".equals(accField.getNodeName())) {
double money = 0;
try {
money = Double.parseDouble(accField.getTextContent());
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (DOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//设置姓名属性 标签元素之间的元素用Element对象.getTextContent()
acc.setMoney(money);
}
}
//添加对象到列表
xmlList.add(acc);
}
return xmlList;
}
/**
* 生成xml文档
* @param path 文件路径
* @param fileName 文件名称
* @param data 集合列表
* @return
* @throws ParserConfigurationException
* @throws TransformerException
*/
public static boolean writeXml(String path,String fileName,List<Account> data) throws ParserConfigurationException, TransformerException{
//非法操作
if(path == null || path.length()<=0 ||
fileName == null || fileName.length()<=0 ||
data == null || data.size()<=0) {
System.out.println("ERROR: filePath args is null!");
//返回null列表
return false;
}
File dir = new File(path);
//判断文件是否存在,不存在则创建
if(!dir.exists()) {
dir.mkdirs();
}
//检测文件是否存在
File xmlFile = new File(dir, fileName);
//获取DOM工厂对象
DocumentBuilderFactory bf = DocumentBuilderFactory.newInstance();
//根据工厂对象创建构建者
DocumentBuilder build = bf.newDocumentBuilder();
//根据构建者创建DOM文档树
Document doc = build.newDocument();
//建立根节点
Element rootEle = doc.createElement("accounts");
//将根节点添加到文档树中
doc.appendChild(rootEle);
//循环Account对象列表,构造account的xml表示
for(Account acc:data) {
//构造account节点
Element accEle = doc.createElement("account");
//为account节点设置其属性
accEle.setAttribute("age", String.valueOf(acc.getAge()));
accEle.setAttribute("bankNo", acc.getBankNo());
//添加account节点到accounts上
rootEle.appendChild(accEle);
//添加id子标签
Element idEle = createSubElement(doc,"id",acc.getId());
//添加id节点到account节点
accEle.appendChild(idEle);
//添加name子标签
Element nameEle = createSubElement(doc,"name",acc.getName());
//添加id节点到account节点
accEle.appendChild(nameEle);
//添加money子标签
Element moneyEle = createSubElement(doc,"money",String.valueOf(acc.getMoney()));
//添加id节点到account节点
accEle.appendChild(moneyEle);
}
//将添加的树状结构写入到doc
TransformerFactory factory = TransformerFactory.newInstance();
Transformer tf = factory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(xmlFile);
tf.transform(source, result);
return true;
}
/**
* 建立一个含有简单文本内容的Element对象
* @param doc
* @param tagName
* @param textContext
* @return
*/
private static Element createSubElement(Document doc,String tagName,String textContext) {
//创建Element对象
Element element = doc.createElement(tagName);
//添加文本内容,文本内容需要添加到TextNode节点
Text text = doc.createTextNode(textContext);
//添加文本内容到标签
element.appendChild(text);
return element;
}
}
今天的内容就分享到这了!期待明天的SAX方式解析XML文档