生成和解析XML

发布于:2021-06-19 13:43:45

一、什么是XML,XML的作用是什么,如何编写XML文件?

XML就是可扩展标记语言与HTML相似都是标记语言。


XML提供的标记都是自定义的;HTML提供的标记都是预先定义好的。


XML用来存储数据的文本格式;HTML是同来设计网页。


XML是一种简单的数据存储语言


如何编写XML文件?


一个简单的XML文件格式





zhangsan
23



lisi
24



说明:


---xml的文件头,表示xml文档开始。与html中的“”作用相似。【土地】


----自定义的xml标记,表示一个xml文件的根元素。【树根】


---自定义的xml标记,表示一个xml文件的根元素中的子元素。【树枝】


id=”1001”, id=”1002”----元素的属性,是一个键值对。


---自定义的xml标记,表示一个xml文件的根元素中的子子元素。【树叶】


zhangsan,23,男...---都是被存储的具体数据值。【果实】


?


注意:


1.标记都是自定义的,成对出现“


2.元素可以携带属性,属性是一个键值对,可以出现多个


????????例如:<小狗 id=”1001”?color=”黑色”>


?3.保存文件的时候,文件的后缀名是以“.xml”结尾


?


例如:


Person类


package com.wangxing.xmldom;
public class Person {
private int perid;
private String pername;
private int perage;
private String peraddress;
public int getPerid() {
return perid;
}
public void setPerid(int perid) {
this.perid = perid;
}
public String getPername() {
return pername;
}
public void setPername(String pername) {
this.pername = pername;
}
public int getPerage() {
return perage;
}
public void setPerage(int perage) {
this.perage = perage;
}
public String getPeraddress() {
return peraddress;
}
public void setPeraddress(String peraddress) {
this.peraddress = peraddress;
}

}

添加数据?



import java.util.List;
import java.util.Properties;


import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class PersonMain {
//main 添加数据
public static void main(String[] args) {
Person person=new Person();
person.setPerid(1001);
person.setPername("测试1");
person.setPerage(23);
person.setPeraddress("西安");

Person person2=new Person();
person2.setPerid(1002);
person2.setPername("测试2");
person2.setPerage(24);
person2.setPeraddress("北京");

List personslist=new ArrayList();
personslist.add(person);
personslist.add(person2);


}
}

?请将上面的personlist集合转换成xml文件?





张三
23
西安


李四
24
北京


二、常见的XML文件的生成方式和解析方式
生成方式
2.1XML文件的生成【Dom生成】

/**
* XML文件的生成【Dom生成】
* java默认的dom生成方式
* @param personlist
* @throws Exception
*/

public static void creatXMLByJavaDom(List personlist)throws Exception {
//得到DOM解析器工厂
DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
//从解析器工厂的解析器
DocumentBuilder documentBuilder=builderFactory.newDocumentBuilder();
//得到Document对象
Document document=documentBuilder.newDocument();
//设置文件头
document.setXmlStandalone(true);
//得到根元素
Element rootElement=document.createElement("personlist");
//循环遍历集合,创建子元素,将子元素添加到根元素
for(Person person:personlist) {
//创建子元素
Element personElement=document.createElement("person");
//为子元素添加属性
personElement.setAttribute("perid", String.valueOf(person.getPerid()));
//创建子子元素
Element nameElement=document.createElement("pername");
Element ageElement=document.createElement("perage");
Element addressElement=document.createElement("peraddress");
//为子子元素添加数据值
nameElement.setTextContent(person.getPername());
ageElement.setTextContent(String.valueOf(person.getPerage()));
addressElement.setTextContent(person.getPeraddress());
//将子子元素添加到子元素
personElement.appendChild(nameElement);
personElement.appendChild(ageElement);
personElement.appendChild(addressElement);
//将子元素添加到根元素
rootElement.appendChild(personElement);
}
//将根元素添加到Document对象中
document.appendChild(rootElement);
// 创建TransformerFactory对象
TransformerFactory tff = TransformerFactory.newInstance();
// 创建 Transformer对象
Transformer tf = tff.newTransformer();

// 输出内容是否使用换行
tf.setOutputProperty(OutputKeys.INDENT,"yes");

//OutputKeys.STANDALONE 设置指定了 Transformer 是否应输出单独的文档声明,其值必须为 yes 或 no。
tf.setOutputProperty(OutputKeys.STANDALONE, "yes");

// method = "xml" | "html" | "text" | expanded name。
//tf.setOutputProperty(OutputKeys.METHOD,"xml");

// 创建xml文件并写入内容
tf.transform(new DOMSource(document), new StreamResult(new File("person1.xml")));
}

2.2使用第三方开发包

A.jdom


package com.wangxing.jdomxml;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

public class CreatXMLByjdom {
public static void creatXMLBuJdom(List personlist) throws Exception{
//创建根元素 Element
Element rootelement=new Element("personlist");
//遍历循环集合,创建子元素,将子元素添加到根元素
for (Person person : personlist) {
//创建子元素
Element personelement=new Element("person");
//设置属性
personelement.setAttribute("perid", String.valueOf(person.getPerid()));
//创建子子元素
Element pernameElement=new Element("pername");
Element perageElement=new Element("perage");
Element peraddressElement=new Element("peraddress");
//设置子子元素文本值
pernameElement.setText(person.getPername());
perageElement.setText(String.valueOf(person.getPerage()));
peraddressElement.setText(person.getPeraddress());
//将子子元素添加到子元素
personelement.addContent(pernameElement);
personelement.addContent(perageElement);
personelement.addContent(peraddressElement);
//将子元素添加到根元素
rootelement.addContent(personelement);
}
//依赖根元素创建Document
Document document=new Document(rootelement);
//输出Docuemnt对象--org.jdom.output.Format
Format format=Format.getCompactFormat();
//设置换行Tab或者空格
format.setEncoding("UTF-8");
format.setIndent(" ");
//创建XMLOutPutter的对象
XMLOutputter xmlOutputter=new XMLOutputter(format);
xmlOutputter.output(document, new BufferedWriter(new FileWriter(new File("jdomCreatXML.xml"))));
System.out.println("生成成功!");
}
}

B. dom4j


/**
* 使用第三方开发包
* dom4j
* 使用第三方开发包Dom4j生成xml
* @throws Exception
*/
public static void creatXMLByDom4j(List personslist) throws Exception{
//得到Document对象
Document document = DocumentHelper.createDocument();
//创建根元素
/* Element addElement(String name)
* 将具有给定名称的新元素节点添加到此分支,并返回对新节点的引用。
* */
Element rootElement=document.addElement("personlist");
//遍历循环集合创建子元素,将子元素添加到根元素
for (Person person : personslist) {
//创建子元素
Element personElement=rootElement.addElement("person");
//添加属性//personElement.addAttribute(属性名, 属性值)
personElement.addAttribute("perid",String.valueOf(person.getPerid()));
//创建子子元素
Element nameElement=personElement.addElement("pername");
Element ageElement=personElement.addElement("perage");
Element addressElement=personElement.addElement("peraddress");
//为子子元素设置数据值
nameElement.setText(person.getPername());
ageElement.setText(String.valueOf(person.getPerid()));
addressElement.setText(person.getPeraddress());
//循环结束--一个集合元素遍历完毕

}
//设置生成xml的格式
OutputFormat format=OutputFormat.createPrettyPrint();
//设置编码格式
format.setEncoding("UTF-8");
//创建xml字符输出流
XMLWriter xmlWriter=new XMLWriter(new FileOutputStream(new File("dom4jperson1.xml")),format);
//设置是否转义,默认使用转义字符
xmlWriter.setEscapeText(false);
//写出Document对象
xmlWriter.write(document);
//关闭流
xmlWriter.close();
}

C.通过字符串拼接的方式


/**
* 通过拼接字符串的方式创建一个xml文件
* @param personlist
* @throws Exception
* @throws Exception
*/
public static void createXMLStr(List personlist) throws Exception{
//定义一个保存拼接好的字符串变量
String xmlcontent=null;
//为了拼接字符串更加方便我峨嵋你使用stringbuilder类拼接字符串
StringBuilder stringBuilder=new StringBuilder();
stringBuilder.append("");
stringBuilder.append("
");
stringBuilder.append("");
stringBuilder.append("
");
//遍历需要被生成xml文件的集合
for(Person person:personlist){
stringBuilder.append(" ");
stringBuilder.append("
");
stringBuilder.append(" "+person.getPername()+"");
stringBuilder.append("
");
stringBuilder.append(" "+person.getPerage()+"");
stringBuilder.append("
");
stringBuilder.append(" "+person.getPeraddress()+"");
stringBuilder.append("
");
stringBuilder.append("
");
stringBuilder.append("
");
}
stringBuilder.append("
");
xmlcontent=stringBuilder.toString();
System.out.println(xmlcontent);
//创建输出流对象,将创建好的xml,保存到文件中
/* OutputStream outputStream=new FileOutputStream(new File("strperson.xml"));
outputStream.write(xmlcontent.getBytes());
outputStream.flush();
outputStream.close();
*/
/*使用缓冲流的优缺点:
* 优点:效率高,每次写出时会先缓存到缓冲中,等到缓冲满后在一次性写出
* 减少了写出次数,提高了效率,使用字符流 也是提高效率
* 缺点:由于缓冲的存在,写出时可能不能第一时间写出数据
* 接收端可能无法及时获取到数据
*
* 不带缓冲的流读取到一个字节或字符,就直接写出数据
* */
BufferedWriter bufferedWriter= new BufferedWriter(new FileWriter(new File("strperson.xml")));
bufferedWriter.write(xmlcontent);
bufferedWriter.flush();
if (bufferedWriter!=null) {
bufferedWriter.close();
}

}

解析方式

实际上就是将xml文件中保存的数据取出,转换成java对象


    DOM(Document?Object?Model)解析

????????????Java默认的 Dom ?/ ?dom4j ?/ ?jdom


将整个xml文件读取成一个Document对象,然后从Document对象中得到根元素,再从根元素中得到子元素,接着从子元素中得到子子元素,最后从子子元素中得到数据值。


1.Java默认的Dom解析xml


package com.wangxing.xmldom;

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 ParseXMLDom {
public static void main(String[] args) throws Exception {
//遍历解析好的集合
List personlist=parseXMLByDom();
for (Person person : personlist) {
System.out.println(person.getPerid()+"
"+person.getPername()+"
"+person.getPerage()+"
"+person.getPeraddress());
}
}

public static List parseXMLByDom() throws Exception{
//定义保存对象的集合
List personlist=new ArrayList();
//得到解析器工厂对象
DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
//得到解析器
DocumentBuilder documentBuilder=documentFactory.newDocumentBuilder();
//将需要被解析的xml文件读取成Document对象
Document document=documentBuilder.parse(new File("person1.xml"));

//从Document对象中取出一组子元素
NodeList personNodeList=document.getElementsByTagName("person");
for(int i=0;i //创建Person对象用来保存解析出的数据值
Person person=new Person();
//得到子元素 --第几个节点
Node personNode=personNodeList.item(i);
//得到默认的属性值
String nodeName=personNode.getAttributes().item(0).getNodeName()+"="+personNode.getAttributes().item(0).getNodeValue();
System.out.println(nodeName);
String perid=personNode.getAttributes().item(0).getNodeValue();
person.setPerid(Integer.parseInt(perid));
//从子元素中得到包含有子子元素的一组集合
NodeList nodeList=personNode.getChildNodes();
//遍历
for(int j=0;j //得到子子元素
Node Cnode=nodeList.item(j);
//得到子子元素的文本值
if (Cnode.getNodeName().equals("pername")) {
String pername=Cnode.getTextContent();
person.setPername(pername);
}
if (Cnode.getNodeName().equals("perage")) {
String perage=Cnode.getTextContent();
person.setPerage(Integer.parseInt(perage));
}
if (Cnode.getNodeName().equals("peraddress")) {
String address=Cnode.getTextContent();
person.setPeraddress(address);
}

}
//将解析好的person对象装入集合
personlist.add(person);
}

return personlist;

}

}

?


使用dom4j解析xml

package com.wangxing.dmo4jxml;
/**
* 使用Dom4j方式解析XML
* @author 14336
*
*/

import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class ParseXMLByDom4j {
public static List parseXMLByDom4j() throws Exception{
//定义保存对象的集合
List personlist=new ArrayList();
//创建xml解析器对象
SAXReader saxReader=new SAXReader();
//通过解析器对象读取XML文件为一个Document【org.Dom4j】对象
Document document=saxReader.read("dom4jperson1.xml");
//得到根元素
Element rootElement=document.getRootElement();
//从根元素中得到一组person子元素
/*rootElement.elements();
* 返回此元素中包含的元素。
* 如果此元素不包含任何元素,则此方法返回空列表。
* 列表由元素支持,因此对列表的更改将反映在元素中,
* 尽管情况并非相反。
*
* 返回:
* 此元素中所有元素的列表。
* */
List perElement=rootElement.elements();
//遍历子元素列表,并且保存数据值
for (Element element : perElement) {
//创建一个保存数据值的Person对象
Person person=new Person();
//得到字元素的属性值,并保存在person中
person.setPerid(Integer.parseInt(element.attributeValue("perid")));
//得到子子元素,并保存在person中
String pername=element.element("pername").getText();
person.setPername(pername);
String perage=element.element("perage").getText();
person.setPerage(Integer.parseInt(perage));
String peraddress=element.element("peraddress").getText();
person.setPeraddress(peraddress);
//将保存完数据的person对象添加到集合中
personlist.add(person);
}
return personlist;
}
}

使用jdom解析xml

package com.wangxing.jdomxml;
/**
* 解析XML类
* @author 14336
*
*/

import java.util.ArrayList;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

public class JieXiXMLByJDom {
/**
* 使用jdom解析xml
* @throws Exception
* @throws JDOMException
*/
public static List parseXMLByJdom() throws JDOMException, Exception{
//定义保存对象的集合
List personlist=new ArrayList();
//创建person对象
Person person=null;
//得到解析器对象
SAXBuilder saxBuilder=new SAXBuilder();
//读取要解析的XML文件成docuemnt
Document document=saxBuilder.build("jdomCreatXML.xml");
//得到根元素
Element rootElement=document.getRootElement();
//从根元素中得到一组person的子元素
List elementlist=rootElement.getChildren();
for (Element element : elementlist) {
//创建person对象来保存解析出的数据值
person=new Person();
//得到属性值
String perid=element.getAttributeValue("perid");
//得到子子元素
Element pernameElement=element.getChild("pername");
Element perageElement=element.getChild("perage");
Element peraddressElement=element.getChild("peraddress");
//得到子子元素的文本值
String pername=pernameElement.getText();
String perage=perageElement.getText();
String peraddress=peraddressElement.getText();

//保存值到person对象中
person.setPerid(Integer.parseInt(perid));
person.setPername(pername);
person.setPeraddress(peraddress);
person.setPerage(Integer.parseInt(perage));
//将person对象保存到集合中
personlist.add(person);

/*
//创建Person对象用来保存解析出的数据值
Person person2=new Person();
person2.setPerid(Integer.parseInt(element.getAttributeValue("perid")));
person2.setPername(element.getChildText("pername"));
person2.setPeraddress(element.getChildText("peraddress"));
person2.setPerage(Integer.parseInt(element.getChildText("perage")));
//将保存完数据值的person对象装入集合
personlist.add(person2);
*/
}


return personlist;
}

}

DOM(Document?Object?Model)解析的原理:


就是需要被解析的xml文件,读取成一个文档树【Document?对象】,依据提供的开发类库和方法从文档树中得到根元素,再从根元素中得到子元素,从子元素中的到子子元素,再得到具体的数据值。


优点:结构清晰明了。


缺点:通常需要加载整个XML文档来构造层次结构,消耗资源大.


?


SAX(Simple?API?for?XML)解析

?


/**
* 使用sax解析xml
* @throws Exception
* @throws ParserConfigurationException
*
*/
public static List parseXMLBySax() throws ParserConfigurationException, Exception{
//定义保存对象的集合
List personlist=new ArrayList();
//得到SAX解析工厂
SAXParserFactory saxParserFactory=SAXParserFactory.newInstance();
//通过解析工厂对象得到SAX解析对象
SAXParser saxParser=saxParserFactory.newSAXParser();

//解析方法的参数
//参数一 --File 对象【被解析的xml文件】
//参数二--DefaultHandler对象【具体的xml解析过程】Default--默认的 Handler--处理程序
//需要创建一个DefaultHandler类的子类,重写解析过程
MyDefaultHandler defaultHandler=new MyDefaultHandler();
saxParser.parse(new File("person1.xml") ,defaultHandler );
personlist=defaultHandler.getPersonList();
return personlist;
}

由于SAX解析发方法需要一个默认的处理程序所以,我们需要根据自己的需求重写解析方法


package com.wangxing.SAXXML;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
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;

/**
* 2.SAX(Simple?API?for?XML)解析
*/
public class MyDefaultHandler extends DefaultHandler {
private List personlist=null;
private Person person=null;
private String elementName="";
public List getPersonList(){
return personlist;
}

/**
* 文档开始的解析方法
*/
@Override
public void startDocument() throws SAXException {
personlist=new ArrayList();
}

/**
* 元素开始的解析方法
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
/*
* 识别元素开始标签,<> 以/作为区分
* attributes.getValue("perid");
* 返回属性的值
* */
if (qName.equals("person")) {
person=new Person();
//得到perid的属性值 --根据属性名得到值,感觉像键值对?
String perid=attributes.getValue("perid");
person.setPerid(Integer.parseInt(perid));
}
if (qName.equals("pername")) {
elementName=qName;
}
if (qName.equals("perage")) {
elementName=qName;
}
if (qName.equals("peraddress")) {
elementName=qName;
}
}
/**
* 读取文本值数据的方法
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String value=new String(ch,start,length);
if (elementName.equals("pername")) {
person.setPername(value);
}
if (elementName.equals("perage")) {
person.setPerage(Integer.parseInt(value));
}
if (elementName.equals("peraddress")) {
person.setPeraddress(value);
}
}

/**
* 元素结束的解析方法
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("person")) {
personlist.add(person);
person=null;
elementName="";
}else{
elementName="";
}
}
/**
* 文档结束的解析方法
*/
@Override
public void endDocument() throws SAXException {
}

}

测试类:


package com.wangxing.SAXXML;

import java.util.List;

public class PersonMain {
// main 添加数据
public static void main(String[] args) throws Exception, Exception {
List personslist=MyDefaultHandler.parseXMLBySax();
for (Person person : personslist) {
System.out.println(person.getPerid()+"
"+person.getPername()
+"
"+person.getPerage()
+"
"+person.getPeraddress());
System.out.println("-------------");
}
}
}

SAX(Simple?API?for?XML)解析xml文件的原理:


是基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的标签的时候,它可以激活一个回调方法,告诉该方法指定的标签已经找到,如果这个指定的标记中中有我们需要数据值就解析,没有就不用处理。


读取一个元素,判断这一个元素属于xml文件的哪一个元素【文档开始/文档结束/标记开始/标记结束/文本元素】,不同的元素触发不同的方法来执行解析数据,如果当前元素中没有数据值就跳过读取下一个元素。


优点:


1.只在读取数据时检查数据,不需要保存在内存中?


2.可以在某个条件得到满足时停止解析,不必解析整个文档。


3.效率和性能较高,能解析大于系统内存的文档。


缺点:没有清晰的解析结构


?


三、XML文件解析方式的区别

DOM(Document?Object?Model)解析的原理


就是需要被解析的xml文件,读取成一个文档树【Document?对象】,依据提供的开发类库和方法从文档树中得到根元素,再从根元素中得到子元素,从子元素中的到子子元素,再得到具体的数据值。


优点:结构清晰明了。


缺点:通常需要加载整个XML文档来构造层次结构,消耗资源大.


?


SAX(Simple?API?for?XML)解析xml文件的原理


是基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的标签的时候,它可以激活一个回调方法,告诉该方法指定的标签已经找到,如果这个指定的标记中中有我们需要数据值就解析,没有就不用处理。


优点:


1.只在读取数据时检查数据,不需要保存在内存中?


2.可以在某个条件得到满足时停止解析,不必解析整个文档。


3.效率和性能较高,能解析大于系统内存的文档。


缺点:没有清晰的解析结构

相关推荐

最新更新

猜你喜欢