解析XML常见的四种方法分别是:
Dom4j、SAX、DOM、JDOM ,个人对四种方式的理解中Dom4j是比较常用性能也比较高的解析方式,如常见框架解析的XML配置文件也多为DOM4j方式。DOM方式需要对将整个XML文档调入内存生成DOM树驻留在内存中,耗费内存空间,但比较适合需要频繁更改XML文档的情况,而SAX方式不需要将XML一次性读进内存在进行解析,而是类似边读边解析,对内存要求较小。
一、Dom4j
使用Dom4j 将List<Person>对象生成XML文件
public class DOM4jTest {
public static void main(String[] args) throws Exception {
List<Person> list = new ArrayList<Person>();
Person person1=new Person(11, "张三1", "女", "北京", 20);
Person person2=new Person(12, "张三2", "女", "上海", 21);
Person person3=new Person(13, "张三3", "女", "广州", 22);
Person person4=new Person(21, "李四1", "男", "北京", 20);
Person person5=new Person(22, "李四2", "男", "上海", 21);
Person person6=new Person(23, "李四3", "男", "广州", 22);
person1.setMate(person4);//增加配偶
person2.setMate(person5);//增加配偶
person3.setMate(person6);//增加配偶
list.add(person1);
list.add(person2);
list.add(person3);
Element root = DocumentHelper.createElement("Persons");// 创建根节点Persons
Document document = DocumentHelper.createDocument(root);
for (Person person : list) {
Element element = root.addElement("Person");//创建子节点Person
element.addAttribute("num", person.getNum()+"");//加入属性num
Element name=element.addElement("name");//person创建子节点name
name.setText(person.getName());
Element sex=element.addElement("sex");
sex.setText(person.getSex());
Element age=element.addElement("age");
age.setText(person.getAge()+"");
Element mate=element.addElement("mate");
Element num=mate.addElement("num");
num.setText(person.getMate().getNum()+"");
Element name_mate=mate.addElement("name");
name_mate.setText(person.getMate().getName());
Element sex_mate=mate.addElement("sex");
sex_mate.setText(person.getMate().getSex());
Element age_mate=mate.addElement("age");
age_mate.setText(person.getMate().getAge()+"");
}
OutputFormat format = new OutputFormat("\r", true);
XMLWriter xmlWriter = new XMLWriter(new OutputStreamWriter(new
FileOutputStream("d:\\Persons.xml"),"UTF-8") ,format);
xmlWriter.write(document);
xmlWriter.close();
}
结果:
使用Dom4j解析该XML
public class DOM4jTest {
public static void main(String[] args) throws Exception {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File("D:\\Persons.xml"));
Element root = document.getRootElement(); // 获取根节点
readElement(root);
}
private static void readElement(Element root) {
// TODO Auto-generated method stub
List<Attribute> attrlist=root.attributes();
for (Attribute attribute : attrlist) {
System.out.println(attribute.getName()+" "+attribute.getValue());
}
List<Element> elementlist=root.elements();
for (Element element : elementlist) {
System.out.println(element.getName()+" "+element.getTextTrim());
readElement(element);
}
}
}
结果:
二、SAX
解析XML,需要传入一个继承了DefaultHandler并复习其主要方法的类,或直接传入匿名内部类。startDocument()和endDocument()方法分别是开始读取和读取完毕执行,读取XML方法顺序是Element相关方法(读取节点名和Attributes )-->characters相关方法读取两结点之间的Text
package XML;
import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXTest {
public static void main(String[] args) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
// step2: 获得SAX解析器实例
SAXParser parser = factory.newSAXParser();
// step3: 开始进行解析
parser.parse(new File("D:\\Persons.xml"), new DefaultHandler() {//传入匿名内部类 复写DefaultHandler主要方法
@Override
public void startDocument() throws SAXException {
// System.out.println("parse began");
}
@Override
public void endDocument() throws SAXException {
// System.out.println("parse finished");
}
@Override
public void startElement(String uri, String localName,
String qName, Attributes attributes) throws SAXException {
System.out.print(qName);
for (int i = 0; i < attributes.getLength(); i++) {
System.out.println(attributes.getQName(i) + "=" + attributes.getValue(i));
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
// super.characters(ch, start, length);读取Text部分
System.out.println(new String(ch, start, length).trim());
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// System.out.println("finish element");
}
});
}
}
结果:
三、JDom
生成Xml
public class JDomTest {
public static void main(String[] args) throws Exception {
Document document = new Document();
Element root = new Element("Persons");
document.addContent(root);
// comment 注释
Comment comment = new Comment("可以添加注释");
root.addContent(comment);
Element person = new Element("Person");
person.setAttribute("id", "201501");
root.addContent(person);
Element name = new Element("name");
name.setText("liuli");
Element age = new Element("age");
age.setText("25");
person.addContent(name).addContent(age);
Format format = Format.getPrettyFormat();
// format.setIndent("\r");
format.setEncoding("UTF-8");
XMLOutputter out = new XMLOutputter(format);
out.output(document, new OutputStreamWriter(new FileOutputStream("jdom.xml"), "UTF-8"));
}
}
结果:
读取XML
public class JDomTest {
public static void main(String[] args) throws Exception {
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(new File("Persons.xml"));
Element root = doc.getRootElement();
System.out.println(root.getName());
List<Element> elements = root.getChildren();
readXml(elements);
XMLOutputter out = new XMLOutputter(Format.getPrettyFormat().setIndent(
" "));
out.output(doc, new FileOutputStream("newPerson.xml"));
}
private static void readXml(List<Element> elements) {
for (Element element : elements) {
System.out.println(element.getName()+element.getTextTrim());
List<Attribute> attribute = element.getAttributes();
for (Attribute attr : attribute) {
System.out.println(attr.getName() + "=" + attr.getValue());
}
readXml(element.getChildren());
}
}
}
打印结果:
四、DOM
public class DOMTest {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File("Persons.xml"));
// 获得根元素结点
Element root = doc.getDocumentElement();
readXml(root);
}
static void readXml(Element element) {
String tagName = element.getNodeName();
NodeList children = element.getChildNodes();
System.out.print(tagName);
// element元素的所有属性所构成的NamedNodeMap对象,需要对其进行判断
NamedNodeMap map = element.getAttributes();
// 如果该元素存在属性
if (null != map) {
for (int i = 0; i < map.getLength(); i++) {
// 获得该元素的每一个属性
Attr attr = (Attr) map.item(i);
String attrName = attr.getName();
String attrValue = attr.getValue();
System.out.print(attrName + "=" + attrValue );
}
}
for (int i = 0; i < children.getLength(); i++) {
Node node = children.item(i);
// 获得结点的类型
short nodeType = node.getNodeType();
if (nodeType == Node.ELEMENT_NODE) {
// 是元素,递归
readXml((Element) node);
} else if (nodeType == Node.TEXT_NODE) {
System.out.print(node.getNodeValue());
} else if (nodeType == Node.COMMENT_NODE) {
Comment comment = (Comment) node;
// 注释内容
String data = comment.getData();
System.out.println(data);
}
}
}
}
结果: