生成和解析XML
1.什么是XML?xml的作用?如何编写xml?
XML就是可扩展标记语言。【是一种简单的数据存储语言】
前面我们学习的HTML也是一种标记语言。
HTML–超文本标记语言—制作网页—提供一组静态的标记元素,无法扩展。
XML–可扩展标记语言–是一种简单的数据存储语言–没有固定的标记元素,在使用的时候可以根据自己的需要创造一个。
比较一下html与xml
XML—数据存储----标记
XML的文件规则:
1.可以在可扩展标记语言文件的内容包括几乎所有的万国码Unicode字符,元素和属性的名称也可以由非ascii字符组成;
2.标签由包围在一个小于号(<)和一个大于号(>)之间的文本组成,例如<标记>;
3.起始标签(外国语:starttag)表示一个特定区域的开始,例如<起始>;
4.结束标签(外国语:end tag)定义了一个区域的结束,除了在小于号之后紧跟着一个斜线(/)外,和起始标签基本一样,例如</结束>;
5.标准通用标记语言还定义了标签的特性“属性”,它们是定义在小于号和大于号之间的值,例如<图片 源=“自拍照.jpg”>中的“源”特性。
<图片 源=“自拍照.jpg”>—我们自己定义的一个xml元素/标记
源=“自拍照.jpg”----表示这个标记的一个属性
源–属性名称
“自拍照.jpg”—属性值
一个简单的XML文件格式
<?xml version="1.0" encoding=”utf-8”?>
<students>
<student id=”1001” >
<name>zhangsan</name>
<age>23</age>
<sex>男</sex>
</student>
<student id=”1002”>
<name>lisi</name>
<age>24</age>
<sex>女</sex>
</student>
</students>
在上面的xml文件中
<?xml version="1.0" encoding=”utf-8”?> --文件头
<students>/</students>---根元素 【不能省略】我们自己定义
<student>/</student>-----子元素,可以有多个,也可以只有一个,我们自己定义
<name>/</name>,<age>/</age>,<sex>/</sex>--子子元素【孙子元素】我们自己定义
id=”1001”---属性 ,出现在开始标记中,可以有多个。
zhangsan、23、男 /lisi、24、女---文本元素【真实的被xml存储起来的真实的数据值】
所有的元素都是成对出现。
2.Xml文件的生成方式和解析方式?
Dom生成:
package com.clic369.test;
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.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.clic369.bean.Person;
import com.clic369.util.XMHelper;
public class CreateXML {
/**
* 测试Dom生成XML
* @throws Exception
*/
@Test
public void testCreateDomXML()throws Exception{
//得到需要的数据
List<Person> personlist= XMHelper.getPersonData();
//得到DOM解析器工厂
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
//从解析器工厂的解析器
DocumentBuilder builder=factory.newDocumentBuilder();
//得到Document对象
Document document= builder.newDocument();
// 不显示standalone="no"
document.setXmlStandalone(true);
//创建根据元素
Element rootElement = document.createElement("persons");
for(Person per:personlist){
//创建子元素
Element personElement = document.createElement("person");
//为子元素添加属性
personElement.setAttribute("perid",String.valueOf(per.getPerid()));
//创建name子子元素
Element pernameElement = document.createElement("pername");
//为子子元素设置文本数据
pernameElement.setTextContent(per.getPername());
//创建age子子元素
Element perageElement = document.createElement("perage");
//为子子元素设置文本数据
perageElement.setTextContent(String.valueOf(per.getPerage()));
//创建address子子元素
Element peraddressElement = document.createElement("peraddress");
//为子子元素设置文本数据
peraddressElement.setTextContent(per.getPeraddress());
//将子子元素添加到子元素
personElement.appendChild(pernameElement);
personElement.appendChild(perageElement);
personElement.appendChild(peraddressElement);
//将子元素添加到根元素
rootElement.appendChild(personElement);
}
//将根元素添加到Document对象
document.appendChild(rootElement);
// 创建TransformerFactory对象
TransformerFactory tff = TransformerFactory.newInstance();
// 创建 Transformer对象
Transformer tf = tff.newTransformer();
// 输出内容是否使用换行
tf.setOutputProperty(OutputKeys.INDENT, "yes");
// 创建xml文件并写入内容
tf.transform(new DOMSource(document), new StreamResult(new File("person1.xml")));
}
}
二 dom4j生成XML
package com.clic369.test;
import java.io.File;
import java.io.FileOutputStream;
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;
import org.junit.Test;
import com.clic369.bean.Person;
import com.clic369.util.XMHelper;
public class CreateXML {
//通过第三方的开发库生成xml文件
//1.dom4j
//下载dom4j开发包
/**
* 通过dom4j开发包来生成xml
* @throws Exception
*/
@Test
public void testCreateDom4jXML()throws Exception{
//得到需要的数据
List<Person> personlist= XMHelper.getPersonData();
//得到Document对象
Document document=DocumentHelper.createDocument();
//创建根节点
Element rootElement= document.addElement("persons");
for(Person per:personlist){
//创建子元素
Element personElement=rootElement.addElement("person");
//设置子元素的熟悉
personElement.addAttribute("perid",String.valueOf(per.getPerid()));
//创建name子子元素
Element pernameElement=personElement.addElement("pername");
//设置文本数据
pernameElement.setText(per.getPername());
//创建age子子元素
Element perageElement=personElement.addElement("perage");
//设置文本数据
perageElement.setText(String.valueOf(per.getPerage()));
//创建address子子元素
Element peraddressElement=personElement.addElement("peraddress");
//设置文本数据
peraddressElement.setText(per.getPeraddress());
}
//设置生成xml的格式
OutputFormat format = OutputFormat.createPrettyPrint();
// 设置编码格式
format.setEncoding("UTF-8");
//创建XML字符输出流
XMLWriter writer = new XMLWriter(new FileOutputStream(new File("person2.xml")), format);
//设置是否转义,默认使用转义字符
writer.setEscapeText(false);
//写出Document对象
writer.write(document);
//关闭流
writer.close();
}
三 、jdom生成xml文件
package com.clic369.test;
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;
import org.junit.Test;
import com.clic369.bean.Person;
import com.clic369.util.XMHelper;
public class CreateXML {
//2.jdom
// 下载jdom开发包
@Test
public void testCreateJdomXML()throws Exception{
//得到需要的数据
List<Person> personlist= XMHelper.getPersonData();
//创建根元素
Element rootElement= new Element("persons");
for(Person per:personlist){
//创建子元素
Element personElement= new Element("person");
//设置属性
personElement.setAttribute("perid",String.valueOf(per.getPerid()));
//创建name元素
Element pernameElement= new Element("pername");
//设置文本元素
pernameElement.setText(per.getPername());
//创建age元素
Element perageElement= new Element("perage");
//设置文本元素
perageElement.setText(String.valueOf(per.getPerage()));
//创建address元素
Element peraddressElement= new Element("peraddress");
//设置文本元素
peraddressElement.setText(per.getPeraddress());
//将子子元素添加到子元素
personElement.addContent(pernameElement);
personElement.addContent(perageElement);
personElement.addContent(peraddressElement);
//将子元素添加到根元素
rootElement.addContent(personElement);
}
//通过根元素创建Document对象
Document document=new Document(rootElement);
//输出Document对象
Format format = Format.getCompactFormat();
// 设置换行Tab或空格
format.setIndent(" ");
format.setEncoding("UTF-8");
// 创建XMLOutputter的对象
XMLOutputter outputer = new XMLOutputter(format);
//写出Document
outputer.output(document, new FileOutputStream(new File("person3.xml")));
}
/**
* 通过拼接字符串的方式创建一个xml文件
* @param personlist
* @throws Exception
*/
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();
}
XML文件的解析
将xml文件转换成java对象
XML文件的解析实际上就是将xml文件中保存的数据取出,转换成java对象
(1)Dom解析XML文件
package com.clic369.test;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.clic369.bean.Person;
/*
* 解析XML文件
*/
public class ParserXml {
/**
* dom解析XML文件
* @throws Exception
*/
@Test
public void parserDomXml()throws Exception{
//得到解析器工程
DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
//得到解析器对象
DocumentBuilder documentBuilder=builderFactory.newDocumentBuilder();
//通过解析器得到Document对象
//parse执行之后就会读取对应的XML文件到内存中形成一个文档树结构,返回一个文档对象
//我们解析xml文件的过程就是从Document对象中得到自己需要的数据值
Document document=documentBuilder.parse(new File("person3.xml"));
//根据指定的元素名称得到包含有众多子元素的集合
NodeList perlist=document.getElementsByTagName("person");
//保存解析成功后的集合
List<Person> personlist=new ArrayList<Person>();
//遍历包含有众多子元素的集合
for(int i=0;i<perlist.getLength();i++){
//得到具体的某一个子元素对象
Node sunElement=perlist.item(i);
Person person = new Person();
//得到子元素的第一个属性值
int perid=Integer.parseInt(sunElement.getAttributes().item(0).getNodeValue());
person.setPerid(perid);
//得到子元素中包含的子子元素的集合
NodeList perChildList=sunElement.getChildNodes();
//遍历子子元素的集合
for(int j=0;j<perChildList.getLength();j++){
//得到每一个子子元素的对象
Node perchild=perChildList.item(j);
//如何子子元素的名称是“pername”,则获取这个子子元素对应的文件数据值
if(perchild.getNodeName().equals("pername")){
person.setPername(perchild.getTextContent());
}
//如何子子元素的名称是“perage”,则获取这个子子元素对应的文件数据值
if(perchild.getNodeName().equals("perage")){
person.setPerage(Integer.parseInt(perchild.getTextContent()));
}
//如何子子元素的名称是“peraddress”,则获取这个子子元素对应的文件数据值
if(perchild.getNodeName().equals("peraddress")){
person.setPeraddress(perchild.getTextContent());
}
}
personlist.add(person);
}
System.out.println(personlist.size());
for(Person per:personlist){
System.out.println(per.getPerid()+" "+per.getPername()+" "+per.getPerage()+" "+per.getPeraddress());
}
}
}
(2)Dom4j解析XML文件
/**
* 通过DOM4J解析xml文件
*/
@Test
public void parserDom4jXml()throws Exception{
//创建xml解析器对象
SAXReader saxReader=new SAXReader();
//通过解析器对象读取被解析的xml文件一个Document
Document document=saxReader.read(new File("person3.xml"));
//得到根元素
Element rootElement=document.getRootElement();
List<Element> elementlist= rootElement.elements("person");
List<Person> personlist=new ArrayList<Person>();
for(Element personElement:elementlist){
Person person=new Person();
person.setPerid(Integer.parseInt(personElement.attributeValue("perid")));
person.setPername(personElement.element("pername").getText());
person.setPerage(Integer.parseInt(personElement.element("perage").getText()));
person.setPeraddress(personElement.element("peraddress").getText());
personlist.add(person);
}
for(Person per:personlist){
System.out.println(per.getPerid()+" "+per.getPername()+" "+per.getPerage()+" "+per.getPeraddress());
}
}
(3)Jdom解析XML文件
/**
* 通过jdom解析xml文件
*/
@Test
public void parserJdomXml()throws Exception{
//得到解析器对象
SAXBuilder saxBuilder=new SAXBuilder();
//读取被解析的xml文件成document
Document document=saxBuilder.build(new File("person3.xml"));
//得到根元素
Element rootElement= document.getRootElement();
//得到指定的子元素
List<Element> elementList= rootElement.getChildren("person");
List<Person> personlist=new ArrayList<Person>();
for(Element personElement:elementList){
Person person=new Person();
person.setPerid(Integer.parseInt(personElement.getAttributeValue("perid")));
person.setPername(personElement.getChildText("pername"));
person.setPerage(Integer.parseInt(personElement.getChildText("perage")));
person.setPeraddress(personElement.getChildText("peraddress"));
personlist.add(person);
}
for(Person per:personlist){
System.out.println(per.getPerid()+" "+per.getPername()+" "+per.getPerage()+" "+per.getPeraddress());
}
}
(5)Sax解析xml文件
/**
* 通过sax解析xml文件
* 下载 -- 导入 -- sax.jar
*/
@Test
public void parserSaxXml()throws Exception{
//得到SAX解析器工厂
SAXParserFactory saxfac = SAXParserFactory.newInstance();
//从工厂中得到解析器对象
SAXParser saxParser=saxfac.newSAXParser();
//调用解析方法解析xml文件
//参数1--被解析的文件
//参数2--实现解析步骤的具体java类【继承DefaultHandler 】
File f=new File("person3.xml");
MyDefaultHandler dh=new MyDefaultHandler();
saxParser.parse(f, dh);
//System.out.println(dh.getPersonList().size());
for(Person per:dh.getPersonList()){
System.out.println(per.getPerid()+" "+per.getPername()+" "+per.getPerage()+" "+per.getPeraddress());
}
}
package com.clic369.util;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.clic369.bean.Person;
public class MyDefaultHandler extends DefaultHandler{
private List<Person> personList;
private Person person;
private String tempName="";
/**
* 文档开始方法
*/
@Override
public void startDocument() throws SAXException {
personList=new ArrayList<Person>();
}
/**
* 元素开始方法
* String qName--当前开始元素的名称
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName.equals("person")){
person=new Person();
person.setPerid(Integer.parseInt(attributes.getValue("perid")));
}
if(qName.equals("pername")){
tempName=qName;
}
if(qName.equals("perage")){
tempName=qName;
}
if(qName.equals("peraddress")){
tempName=qName;
}
}
/**
* 得到元素文本值的方法
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String info=new String(ch,start,length);
if(tempName.equals("pername")){
person.setPername(info);
}
if(tempName.equals("perage")){
person.setPerage(Integer.parseInt(info));
}
if(tempName.equals("peraddress")){
person.setPeraddress(info);
}
}
/**
* 元素结束方法
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equals("person")){
personList.add(person);
person=null;
tempName="";
}else{
tempName="";
}
}
/**
* 文档结束
*/
@Override
public void endDocument() throws SAXException {
}
/**
* 得到解析后包含有Person对象的java集合
* @return
*/
public List<Person> getPersonList(){
return personList;
}
}
3.XML解析方式的区别?
基础方法
DOM解析 平台无关的官方解析方式
SAX解析 基于事件驱动的解析方式(逐条语句解析)
扩展方法(Java特有)需要导入jar包
JDOM解析
DOM4J解析
优缺点分析:
DOM
优点:
1.>形成了树结构,直观好理解,代码更易编写
2.>解析过程中树结构保留在内存中,方便修改
缺点:
1.>当xml文件较大时,对内存耗费比较大,容易影响解析性能并造成内存溢出
SAX
优点:
1.>采用事件驱动模式,对内存耗费比较小
2.>适用于只需要处理xml中数据时
缺点:
1.>不易编码
2.>很难同时访问同一个xml中的多处不同数据
JDOM
优点:
仅仅使用具体类而不使用接口
缺点:
api大量使用了Collections类
DOM4J
现在比较流行
JDOM的一种智能分支,他合并了许多超出基本xml文档表示的功能
DOM4J使用接口和抽象基本类方法,是一个优秀额Java XML API
具有性能优异,灵活性好,功能强大和极易使用的特点
DOM4J性能更好一些
如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。