1.什么是XML?
XML是可扩展标记语言,HTML是超文本标记语言。
标记语言就是通过一个一个的标记来组织数据的一种语法格式。
与HML超文本标记语言比较的话,XML这种可扩展标记语言它的标记是自
己定义的。
XML中自己定义的标记表示:
例如:<标记名称 属性1=“属性值” 属性2=“属性值”……>具体数据</标记名称>
2.XML作用
存储数据的一种语法格式。
它还可以是一种数据包交换格式。
3.如何编写XML文件
public class Student{
private int stuid;
private String stuname;
private int stuage;
private String stuaddress;
.....
getXXX()/setXXX()
}
Student student=new Student();
student.setStuid(1001);
student.setStuname("zhangsan");
student.setStuage(23);
student.setStuaddress("西安");
将上述java对象组织成一个xml格式的数据做法:
XML类型的数据或文件名【名称.xml】
格式:
<?xml version="1.0" encoding="utf-8"?>——xml类型数据/文件标识
<students>——xml的根元素【必不可少】
<student stuid=”1001”>——xml的子元素,里面有一个属性
<stuname>zhangsan</stuname>—子子元素,中间具体数据值
<stuage>23</stuage>——子子元素,中间具体数据值
<stuaddress>西安</stuaddress>—子子元素,中间具体数据值
</student>
</students>
注意:
1.<?xml version="1.0" encoding="utf-8"?>不能少。
2.根元素只有一个,必不可少。
3.具体的数据值都是由于子元素/子子【孙子】元素保存。
4.如果是一个文件,那么文件的后缀名使用“.xml”。
5.标记都是自己定义的,没有固定的具体标记。
6.子元素和子子元素都是可以有多个的。
4.XML文件的生成
4.1Dom生成
<?xml version="1.0" encoding="utf-8"?>
<studentlist>
<student stuid="1001">
<stuname>zhangsan</stuname>
<stuage>23</stuage>
<stuaddress>西安</stuaddress>
</student>
<student stuid="1002">
<stuname>lisi</stuname>
<stuage>24</stuage>
<stuaddress>北京</stuaddress>
</student>
<student stuid="1003">
<stuname>wangwu</stuname>
<stuage>25</stuage>
<stuaddress>上海</stuaddress>
</student>
</studentlist>
案例:生成上述数据的xml文件
4.1.1 java默认的dom生成
- 方法步骤总结:
- 使用DOM方式生成XML文件有如下几步:
- (1)首先是创建DOM树(即规定XML文件中的内容):
- 创建DocumentBuilderFactory对象
- 通过DocumentBuilderFactory对象创建DocumentBuilder对象
- 通过DocumentBuilder对象的newDocument()方法创建一个Document对象,该对象代表一个XML文件
- 通过Document对象的createElement()方法创建根节点
- 通过Document对象的createElement()方法创建N个子节点,并为他们赋值,再将这些子节点添加到根节点下
- 将根节点添加到Document对象下
- (2)其次是将DOM树转换为XML文件:
- 创建TransformerFactory类的对象
- 通过TransformerFactory创建Transformer对象
- 使用Transformer对象的transform()方法将DOM树转换为XML文件。(该方法有两个参数,第一个参数为源数据,需要创建DOMSource对象并将Document加载到其中;第二个参数为目的文件,即要生成的XML文件,需要创建StreamResult对象并指定目的文件)
public class Student {
private int stuid;
private String stuname;
private int stuage;
private String stuaddress;
public int getStuid() {
return stuid;
}
public void setStuid(int stuid) {
this.stuid = stuid;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public int getStuage() {
return stuage;
}
public void setStuage(int stuage) {
this.stuage = stuage;
}
public String getStuaddress() {
return stuaddress;
}
public void setStuaddress(String stuaddress) {
this.stuaddress = stuaddress;
}
}
import java.io.File;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class XMLHelper {
/**
* java默认的dom生成方式
*
*
*/
public static void createXML(List<Student> stulist) throws Exception {
//得到DOM解析工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//创建DocumentBuilder对象
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
//创建Document对象
Document document = documentBuilder.newDocument();
//设置文档对象的文件头
document.setXmlStandalone(true);
//创建根元素
Element rootelement = document.createElement("studentlist");
//遍历集合
for(Student student:stulist){
//创建子元素
Element ziElement = document.createElement("student");
//为子元素设置属性
ziElement.setAttribute("stuid",String.valueOf(student.getStuid()));
//创建子子元素
Element stunameelement = document.createElement("stuname");
//为子子元素设置具体数据值
stunameelement.setTextContent(student.getStuname());
//创建子子元素
Element stuagelement = document.createElement("stuage");
//为子子元素设置具体数据值
stuagelement.setTextContent(String.valueOf(student.getStuage()));
//创建子子元素
Element stuaddresslement = document.createElement("stuaddress");
//为子子元素设置具体数据值
stuaddresslement.setTextContent(student.getStuaddress());
//将子子元素添加到子元素中
ziElement.appendChild(stunameelement);
ziElement.appendChild(stuagelement);
ziElement.appendChild(stuaddresslement);
//将子元素加到根元素中
rootelement.appendChild(ziElement);
}
//把根元素加到document中
document.appendChild(rootelement);
//将document对象写到xml文件中
File file=new File("student.xml");
//创建transformerFactory对象,这个是专门写这个document的
TransformerFactory transformerFactory = TransformerFactory.newInstance();
//创建Transformer对象
Transformer transformer = transformerFactory.newTransformer();
//输出内容是否使用换行,固定格式不变
transformer.setOutputProperty(OutputKeys.INDENT,"yes");
//创建xml文件并写入
//Source xmlSource, Result outputTarget
Source xmlSource=new DOMSource(document);
Result outputTarget=new StreamResult(file);
transformer.transform(xmlSource, outputTarget);
}
}
import java.util.ArrayList;
import java.util.List;
public class Main {
private static final int List = 0;
public static void main(String[] args) throws Exception {
Student student1=new Student();
student1.setStuid(1001);
student1.setStuname("zhangsan");
student1.setStuage(23);
student1.setStuaddress("西安");
Student student2=new Student();
student2.setStuid(1002);
student2.setStuname("lisi");
student2.setStuage(24);
student2.setStuaddress("北京");
Student student3=new Student();
student3.setStuid(1003);
student3.setStuname("wangwu");
student3.setStuage(25);
student3.setStuaddress("上海");
List<Student> studentlist=new ArrayList<Student>();
studentlist.add(student1);
studentlist.add(student2);
studentlist.add(student3);
XMLHelper.createXML(studentlist);
}
}
输出为:
缺点:xml格式不对,格式效果较差
4.1.2第三方开发包dom4j生成
使用dom4j方式生成XML文件的步骤如下:
- 引入JAR包
- 通过DocumentHelper类的createDocument()创建Document对象
- 通过Document的addElement()方法创建节点
- 通过Element的addAttribute()方法为节点添加属性
- 通过Element的setText()方法为节点设置内容
- 通过OutputFormat的createPrettyPrint()方法创建OutputFormat对象(会自动缩进、换行)
- 创建XMLWriter对象,将目的文件包装成OutputStream传入构造方法中,并将OutputFormat对象一并传入其中
- 通过XMLWriter的write()方法生成XML文件,并将Document对象作为参数传入
- 关闭XMLWriter对象
/**
* dom4j
*
*/
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
public class XMLHelper {
public static void createXML(List<Student> studentlist) throws Exception {
//得到document对象
Document document = DocumentHelper.createDocument();
//创建根元素
Element rootelement = document.addElement("studentlist");
for(Student student:studentlist){
//创建子元素
Element zielement = rootelement.addElement("student");
zielement.addAttribute("stuid", String.valueOf(student.getStuid()));
//创建子子元素
Element nameelement = zielement.addElement("stuname");
nameelement.setText(student.getStuname());
Element ageelement = zielement.addElement("stuage");
ageelement.setText(String.valueOf(student.getStuage()));
Element addresselement = zielement.addElement("stuaddress");
addresselement.setText(student.getStuaddress());
}
//设置编码格式,格式输出
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
//创建xml并写入
//创建XML字符输出流
XMLWriter writer = new XMLWriter(new FileOutputStream(new File("student2.xml")),format);
//设置默认转义字符,不转义
writer.setEscapeText(false);
//写出document对象
writer.write(document);
//关闭流
writer.close();
}
}
格式还是差一行
DOM4J会对某些特殊字符进行自动转义,若不想让DOM4J进行自动转义,我们可以通过XMLWriter的setEscapeText()方法进行设置。默认情况下,DOM4J会自动进行转义,相当于writer.setEscapeText(true);若不想让其自动转义,可使用writer.setEscapeText(false);
4.1.3 第三方开发包jdom生成
使用JDOM方式生成XML文件的步骤如下:
- 创建根节点,通过new Element
- 创建子节点,使用setAttribute()方法为其设置属性,使用setText()方法为其设置节点内容
- 使用父节点的addContent()方法为其添加子节点
- 创建Document对象,并将根节点传入其构造方法中
- 创建XMLOutputter对象
- 使用XMLOutputter对象的output()方法将Document转换成XML文件
//在使用JDOM生成XML时,可自行指定其输出格式,有两种方法可选。
//方法一:创建Format对象(自动缩进、换行)
Format format = Format.getPrettyFormat();
//为XMLOutputter设置Format对象
outputter.setFormat(format);
//方法二:创建Format对象,并设置其换行
//Format format = Format.getCompactFormat();
//format.setIndent("");
/**
* jdom
*
*/
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
public class XMLHelper {
public static void createXML(List<Student> studentlist) throws Exception {
//创建根元素
Element rootelement = new Element("studentlist");
for(Student student:studentlist){
//创建子元素
Element zielement = new Element("student");
zielement.setAttribute("stuid", String.valueOf(student.getStuid()));
//创建子子元素
Element nameelement=new Element("stuname");
nameelement.setText(student.getStuname());
Element ageelement=new Element("stuage");
ageelement.setText(String.valueOf(student.getStuage()));
Element addresselement=new Element("stuaddress");
addresselement.setText(student.getStuaddress());
zielement.addContent(nameelement);
zielement.addContent(ageelement);
zielement.addContent(addresselement);
rootelement.addContent(zielement);
}
//创建Document对象,并将根节点传入其构造方法中
Document document=new Document(rootelement);
//创建XMLOutputter对象
XMLOutputter outputter = new XMLOutputter();
//使用XMLOutputter对象的output()方法将Document转换成XML文件
//在使用JDOM生成XML时,可自行指定其输出格式,有两种方法可选。
//方法一:创建Format对象(自动缩进、换行)
Format format = Format.getPrettyFormat();
//为XMLOutputter设置Format对象
outputter.setFormat(format);
//方法二:创建Format对象,并设置其换行
//Format format = Format.getCompactFormat();
//format.setIndent("");
outputter.output(document, new FileOutputStream(new File("student3.xml")));
}
}
输出:
4.2通过拼接字符串【不推荐】
StringBuilder stringBuilder=new StringBuilder();
stringBuilder.append();
public static void createXML4(List<Person> personlist)throws Exception{
//定义一个保存拼接好的字符串变量
String xmlcontent=null;
//为了拼接字符串更加方便我们使用stringbuilder类拼接字符串
StringBuilder stringBuilder=new StringBuilder();
stringBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
stringBuilder.append("\r\n");
stringBuilder.append("<personlist>");
stringBuilder.append("\r\n");
//遍历需要被生成成xml文件的集合
for(Person person:personlist){
stringBuilder.append("\t<person perid=\""+person.getPerid()+"\">");
stringBuilder.append("\r\n");
stringBuilder.append("\t\t<pername>"+person.getPername()+"</pername>");
stringBuilder.append("\r\n");
stringBuilder.append("\t\t<perage>"+person.getPerage()+"</perage>");
stringBuilder.append("\r\n");
stringBuilder.append("\t\t<peraddress>"+person.getPeraddress()+"</peraddress>");
stringBuilder.append("\r\n");
stringBuilder.append("\t</person>");
stringBuilder.append("\r\n");
}
stringBuilder.append("<personlist>");
xmlcontent=stringBuilder.toString();
System.out.println(xmlcontent);
//创建输出流对象,将创建好的xml,保存到文件中
File file=new File("F:"+File.separator+"personlist.xml");
BufferedWriter out=new BufferedWriter(new FileWriter(file));
out.write(xmlcontent);
out.close();
}
5.XML文件解析
5.1java默认的Dom解析xml
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class XMLHelper {
/**
* java自带dom解析
*
*/
public static List<Student> getStudentlist(String filename) throws Exception{
List<Student> studentlist=new ArrayList<Student> ();
//得到解析器工厂
DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
//得到解析器对象
DocumentBuilder builder = factory.newDocumentBuilder();
//创建Document对象,从文件中读
Document document = builder.parse(new File(filename));
//从Document对象中取出一组子元素
NodeList ziElementlist = document.getElementsByTagName("student");
//遍历子元素集合
for(int i=0;i<ziElementlist.getLength();i++){
Student student=new Student();
Node ziElement = ziElementlist.item(i);
int stuid = Integer.parseInt(ziElement.getAttributes().item(0).getNodeValue());//拿到id
student.setStuid(stuid);
//得到子子元素集合
NodeList ziziElement = ziElement.getChildNodes();
//遍历子子元素集合
for(int j=0;j<ziziElement.getLength();j++){
Node node = ziziElement.item(j);
String info = node.getTextContent();
if(node.getNodeName().equals("stuname")){
student.setStuname(info);
}
if(node.getNodeName().equals("stuage")){
student.setStuage(Integer.parseInt(info));
}
if(node.getNodeName().equals("stuaddress")){
student.setStuaddress(info);
}
}
studentlist.add(student);
}
return studentlist;
}
}
测试类:
public class Main {
public static void main(String[] args) throws Exception {
List<Student> studentlist = XMLHelper.getStudentlist("student3.xml");
//检验一下有没有问题
for(Student list:studentlist){
System.out.println(list.getStuid()+"\t"+list.getStuaddress()+"\t"+list.getStuname());
}
}
}
输出:
1001 西安 zhangsan
1002 北京 lisi
1003 上海 wangwu
5.2 dom4j解析
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class XMLHelper {
/**
* dom4j解析
*
*/
public static List<Student> getStudentlist(String filename) throws Exception{
List<Student> studentlist=new ArrayList<Student> ();
//得到docement对象
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(filename));
//得到根元素
Element rootElement = document.getRootElement();
//得到子元素集合
List<Element> zielements = rootElement.elements("student");
//遍历子元素集合
for(int i=0;i<zielements.size();i++){
Student student = new Student();
Element zielement = zielements.get(i);
String stuid1 =zielement.attribute("stuid").getValue();
int stuid = Integer.parseInt(stuid1);
student.setStuid(stuid);
List<Element> zizielements = zielement.elements();
//遍历子子元素集合
for(int j=0;j<zizielements.size();j++){
String name = zizielements.get(j).getName();
String info = zizielements.get(j).getText();
if(name.equals("stuname")){
student.setStuname(info);
}
if(name.equals("stuage")){
student.setStuage(Integer.parseInt(info));
}
if(name.equals("stuaddress")){
student.setStuaddress(info);
}
}
studentlist.add(student);
}
return studentlist;
}
}
输出为:
1001 西安 zhangsan
1002 北京 lisi
1003 上海 wangwu
5.3 jdom解析
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
public class XMLHelper {
/**
* jdom解析xml
*
*/
public static List<Student> getStudentlist(String filename) throws Exception{
List<Student> studentlist=new ArrayList<Student> ();
//得到docement对象
SAXBuilder builder = new SAXBuilder();
Document document = builder.build(new File(filename));
//得到根元素
Element rootElement = document.getRootElement();
//得到子元素集合
List<Element> zilist = rootElement.getChildren("student");
//遍历子元素集合
for(Element zielements:zilist){
Student student = new Student();
String idname = zielements.getAttributeValue("stuid");
int stuid = Integer.parseInt(idname);
student.setStuid(stuid);
//得到子子元素和属性值
Element nameelement = zielements.getChild("stuname");
String name = nameelement.getText();
Element ageelement = zielements.getChild("stuage");
int age = Integer.parseInt(ageelement.getText());
Element addresselement = zielements.getChild("stuaddress");
String address = addresselement.getText();
student.setStuname(name);
student.setStuage(age);
student.setStuaddress(address);
studentlist.add(student);
}
return studentlist;
}
}
DOM解析原理就是需要被解析的xml文件,读取成一个文档【Document 对象】,依据提供的开发类库和方法从文档树中得到根元素,再从根元素中得到子元素,从子元素中的到子子元素,再得到具体的数据值。
优点:结构清晰明了。
缺点:通常需要加载整个XML文档来构造层次结构,消耗资源大。
5.4 SAX(Simple API for XML)解析
优点:1.只在读取数据时检查数据,不需要保存在内存中
2.可以在某个条件得到满足时停止解析,不必解析整个文档。
3.效率和性能较高,能解析大于系统内存的文档。
缺点:没有清晰的解析结构。
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws Exception {
List<Student> studentlist = XMLHelper.getStudentlist("student3.xml");
//检验一下有没有问题
for(Student list:studentlist){
System.out.println(list.getStuid()+"\t"+list.getStuaddress()+"\t"+list.getStuname());
}
}
}
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MyDefaultHandler extends DefaultHandler{
private List<Student> studentlist=null;
private Student student=null;
private String elementName="";
/**
* 得到解析器数据
*
*/
public List<Student> getStudentList() {
return studentlist;
}
/**
* 文档开始
*/
@Override
public void startDocument() throws SAXException {
studentlist=new ArrayList<Student>();
}
/**
* 文档结束
*/
@Override
public void endDocument() throws SAXException {
}
/**
* 元素开始
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName.equals("student")){
student=new Student();
int stuid=Integer.parseInt(attributes.getValue("stuid"));
student.setStuid(stuid);
}
if(qName.equals("stuname")){
elementName=qName;
}
if(qName.equals("stuage")){
elementName=qName;
}
if(qName.equals("stuaddress")){
elementName=qName;
}
}
/**
* 元素结束
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
elementName="";
if(qName.equals("student")){
studentlist.add(student);
student=null;
}
}
/**
* 得到数据值
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String info=new String(ch,start,length);
if(elementName.equals("stuname")){
student.setStuname(info);
}
if(elementName.equals("stuage")){
student.setStuage(Integer.parseInt(info));;
}
if(elementName.equals("stuaddress")){
student.setStuaddress(info);;
}
}
}
SAX(Simple API for XML)解析xml文件的原理是基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的标签的时候,它可以激活一个回调方法,告诉该方法指定的标签已经找到,如果这个指定的标记中中有我们需要数据值就解析,没有就不用处理。读取一个元素,判断这一个元素属于xml文件的哪一个元素【文档开始/文档结束/标记开始/标记结束/文本元素】,不同的元素触发不同的方法来执行解析数据,如果当前元素中没有数据值就跳过读取下一个元素。