XML:X (extensible: 可扩展的) M (markup 标记/标签) L (language 语言);可扩展的标记语言!
在CDATA区中书写特殊符号时,忽略其本性,变成普通的字符串。
如下CDATA中的字符串‘10<5’,为了避免将字符串中的‘<’号当成标签部分,所以将整个字符串放入CDATA区。
<student >
<xx> xx>
student >
xsd 是xml结构定义(XML Schemas Definition)
xsd 是dtd的替代品,比dtd高端;实现和dtd相同的功能。
xsd的优点:
- dom 解析的原理解析xml的时候,把文档中的所有元素按照其出 现的层次关系,在内存中构造出树形结构.
- dom的优点就是可以遍历和修改节点的内容
- 缺点是内存压力较大, 解析较慢
● 是一种xml 解析的替代方法
● 相对比dom 方式,sax 是一种速度更快,更有效的方法 ● 不能修改节点内容
● 仅适用具体的类,而不用接口,不灵活
● JDOM的一种智能的分支,合并了许多超出基本XML文档的功能
● 著名的底层框架hibernate就是用dom4j来解析。
前两种属于基础方法,是官方提供的与平台无关的解析方式。
后两种属于扩展方法,他们是在基础的方法之上扩展出来的,只适用于java平台。
dom4j性能最高,其次是SAX,、dom和jdom表现不好(解析 10兆大小的xml文件,就内存溢出了。)
XML文件内容如下:
<persons>
<person>
<name>至尊宝name>
<age> 9000age>
person>
persons>
java代码如下:
package xml;
import java.io.IOException;
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;
/*
* SAX解析流程
*/
public class XmlTest01 {
public static void main(String[] args) throws Exception {
//SAX解析
//1、获取解析工厂
SAXParserFactory factory=SAXParserFactory.newInstance();
//2、从解析工厂获取解析器
SAXParser parse =factory.newSAXParser();
//3、编写处理器
//4、加载文档Document注册处理器
PHandler handler=new PHandler();
//5.解析
parse.parse(Thread.currentThread().getContextClassLoader()
.getResourceAsStream("xml/p.xml")
,handler );
}
}
class PHandler extends DefaultHandler{
@Override
//解析开始时运行
public void startDocument() throws SAXException {
System.out.println("---解析文档开始---");
}
@Override
//读取到标签时,获取标签参数运行
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println(qName+"-->解析开始");
}
@Override
//用于读取内容
public void characters(char[] ch, int start, int length)throws SAXException {
String contents = new String(ch, start, length).trim(); //去掉两边的空格
if(contents.length()>0){
System.out.println("内容为->"+contents);
}else{//碰到空格
System.out.println("内容为->"+"空");
}
}
@Override
//读取到结束标签时,运行
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println(qName+"-->解析结束");
}
@Override
//文档解析结束时,即读取到根标签的结束符时,运行
public void endDocument() throws SAXException {
System.out.println("---解析文档结束---");
}
}
运行结果:
—解析文档开始—
persons–>解析开始
内容为->空
person–>解析开始
内容为->空
name–>解析开始
内容为->至尊宝
name–>解析结束
内容为->空
age–>解析开始
内容为->9000
age–>解析结束
内容为->空
person–>解析结束
内容为->空
persons–>解析结束
—解析文档结束—
结果解析:
SAX 解析方法是按照流的方式进行,从上到下依次进行读取。有些内容为空是因为写标签时格式的缩进导致的。
XML文件内容如下:
<persons>
<person>
<name>至尊宝name>
<age> 9000age>
person>
<person>
<name>白晶晶name>
<age> 600age>
person>
persons>
Person类代码如下:
package xml;
public class Person {
private String name;
private int age;
public Person(){
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
sax解析代码如下:
package xml;
import java.io.IOException;
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;
/*
* SAX解析流程
*/
public class XmlTest02 {
public static void main(String[] args) throws Exception {
//SAX解析
//1、获取解析工厂
SAXParserFactory factory=SAXParserFactory.newInstance();
//2、从解析工厂获取解析器
SAXParser parse =factory.newSAXParser();
//3、编写处理器
//4、加载文档Document注册处理器
PersonHandler handler=new PersonHandler();
//5.解析
parse.parse(Thread.currentThread().getContextClassLoader()
.getResourceAsStream("xml/p.xml")
,handler );
//读取数据
List<Person> persons = handler.getPersons();
for(Person p:persons){
System.out.println(p.getName()+"-->"+p.getAge());
}
}
}
class PersonHandler extends DefaultHandler{
private List<Person> persons;
private Person person;
private String tag; //存储当前操作的标签
@Override
//解析开始时运行
public void startDocument() throws SAXException {
System.out.println("---解析文档开始---");
persons = new ArrayList<Person>();
}
@Override
//读取到标签时,获取标签参数运行
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println(qName+"-->解析开始");
if(qName!=null){
tag = qName; //存储标签名
if(tag.equals("person")){ //开始读取一个类,即一个标签
person = new Person();
}
}
}
@Override
//用于读取内容
public void characters(char[] ch, int start, int length)throws SAXException {
String contents = new String(ch, start, length).trim(); //去掉两边的空格
if(tag!=null){//这个判断是为了避免读取空内容
if(tag.equals("name")){
person.setName(contents);
}else if(tag.equals("age")){
if(contents.length()>0){
person.setAge(Integer.valueOf(contents));
}
}
}
}
@Override
//读取到结束标签时,运行
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println(qName+"-->解析结束");
if(qName!=null){//这里由于tag有可能已经为空,所以不能再用tag进行判断
if(qName.equals("person")){
persons.add(person); //成功读取完一个类,添加进容器
}
}
tag = null; //将tag丢弃,准备读取下一个类
}
@Override
//文档解析结束时,即读取到根标签的结束符时,运行
public void endDocument() throws SAXException {
System.out.println("---解析文档结束---");
}
public List<Person> getPersons() {
return persons;
}
public void setPersons(List<Person> persons) {
this.persons = persons;
}
}
运行结果如下:
—解析文档开始—
persons–>解析开始
person–>解析开始
name–>解析开始
name–>解析结束
age–>解析开始
age–>解析结束
person–>解析结束
person–>解析开始
name–>解析开始
name–>解析结束
age–>解析开始
age–>解析结束
person–>解析结束
persons–>解析结束
—解析文档结束—
至尊宝–>9000
白晶晶–>600