目录
一,什么是XML:
定义:XML指的是可扩展标记语言,主要用来传输和存储数据。
XML主要语法规则:
XML标签需要用户自定义
XML标签使用时要关闭<标签名> </标签名>成对存在
XML标签对区分大小写
XML标签必须正确的嵌套
XML文档有且只有一个根元素
XML的属性值要加引号
XML中的空格换行符等会被当做内容读取
更多xml的详情:http://www.w3school.com.cn/xml/index.asp
二,XML的解析
java的中对XML的解析有多种方式,本本文主要使用SAX,拉,DOM三种解析方式。
解析的XML文件内容为:
<?xml version="1.0" encoding="utf-8" ?>
<students>
<student id="1235">
<name>小花</name>
<age>25</age>
<salary>3500</salary>
</student>
<student id="6121">
<name>王五</name>
<age>36</age>
<salary>6000</salary>
</student>
<student id="4851">
<name>里斯</name>
<age>24</age>
<salary>4000</salary>
</student>
</students>
2.1 SAX解析
SAX解析采用事件驱动的方式进行解析,逐行读取XML文件,并逐行解析。
public class Test {
public static void main(String[] args) throws Exception{
//创建SAX解析工厂
SAXParserFactory saxParserFactory=SAXParserFactory.newInstance();
//获取解析器对象
SAXParser parser=saxParserFactory.newSAXParser();
//创建解析器处理对象
MyHandler myHandler=new MyHandler();
//传入xml文件和解析器 开始解析xml
parser.parse(new File("students.xml"),myHandler);
List<Student> list=myHandler.getList();
System.out.println("------------------------");
for (Student s:list) {
System.out.println("姓名:"+s.getName()+",年龄:"+s.getAge()+",工资:"+s.getSalary());
}
}
}
public class Student {
private Integer id;
private String name;
private int age;
private int salary;
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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;
}
}
public class MyHandler extends DefaultHandler {
/***
* 将解析的内容存放到list中
*/
private List<Student> list;
/***
* 用于解析判断
*/
private Student student;
private boolean isName;
private boolean isAge;
private boolean isSalary;
/***
* 文档开始解析 只执行一次
*/
@Override
public void startDocument() throws SAXException {
System.out.println("xml解析开始");
list=new ArrayList<Student>();
}
/***
* 开始标签 每次读到一个标签便从这个方法开始
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//qName 读到的标签的名称
if (qName.equals("student")){
student=new Student();//读到student标签 创建一个学生对象
}else if (qName.equals("name")){
isName=true;
}else if (qName.equals("age")){
isAge=true;
}else if (qName.equals("salary")){
isSalary=true;
}
}
/***
* 当读取到标签 标签内有内容 遍执行此方法 获取标签的内容
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String temp=new String(ch,start,length);
if (isName){
student.setName(temp);
isName=false;
}else if (isAge){
student.setAge(Integer.valueOf(temp));
isAge=false;
}else if (isSalary){
student.setSalary(Integer.valueOf(temp));
isSalary=false;
}
}
/***
* 每读到一个结束的标签 遍执行此方法
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("student")){
list.add(student);//一个student 的标签读完 将该学生对象添加到集合中
}
}
/***
* 整个xml解析结束 只执行一次
*/
@Override
public void endDocument() throws SAXException {
System.out.println("xml文档解析结束");
}
/***
* 获取学生集合对象
* @return
*/
public List<Student> getList(){
return list;
}
}
解析结果:
2.2 PULL解析
PULL解析与SAX解析方式相似,都是事件驱动方式。使用PULL解析需要导入的jar包。
jar包地址:https://download.csdn.net/download/sitansen/10611364
/**
* Pull解析xml
*/
public class PullTest {
static List<Student> list;
static Student student;
static String tag;//用于存放标签
public static void main(String[] args)throws Exception{
//创建解析工厂
XmlPullParserFactory pullParserFactory=XmlPullParserFactory.newInstance();
//创建解析器对象
XmlPullParser pullParser=pullParserFactory.newPullParser();
//传入xml文件
pullParser.setInput(new FileReader("students.xml"));
//开始解析
action(pullParser);
//获取结果
for(Student s:list){
System.out.println("id:"+s.getId()+" ,姓名:"+s.getName()+" ,年龄:"+s.getAge()+" ,工资:"+s.getSalary());
}
}
/**
* 开始解析
* @param pullParser
* @throws Exception
*/
public static void action(XmlPullParser pullParser)throws Exception{
int eventType=pullParser.getEventType();//获取标签类型
while (eventType!=XmlPullParser.END_DOCUMENT){//END_DOCUMENT 用于判断是否解析完
tag=pullParser.getName();//获取标签名
//解析开始
if (eventType==XmlPullParser.START_DOCUMENT){//START_DOCUMENT 文档开始的标签
list=new ArrayList<>();//创建一个list用于存放学生对象
}else if (eventType==XmlPullParser.START_TAG){ //开始标签
if (tag.equals("student")){
student=new Student();
/***
* 获取属性id
*/
int num=pullParser.getAttributeCount();//获取属性的个数
for (int i=0;i<num;i++){
if (pullParser.getAttributeName(i).equals("id")){//判断属性名是否为id
student.setId(Integer.valueOf(pullParser.getAttributeValue(i)));
break;
}
}
}else if (tag.equals("name")){
student.setName(pullParser.nextText());//调用nextText()方法过去name标签后的内容 以下同
}else if (tag.equals("age")){
student.setAge(Integer.valueOf(pullParser.nextText()));
}else if (tag.equals("salary")){
student.setSalary(Integer.valueOf(pullParser.nextText()));
}
}else if (eventType==XmlPullParser.END_TAG){ //student标签结束
if (tag.equals("student")){
list.add(student);//将当前的学生对象存起来
}
}
eventType=pullParser.next();//获取下一个标签的类型
}
}
}
解析结果:
2.3DOM解析
DOM解析与前两种方式不同,DOM解析采用的是将整个XML文件读取进来,再组成一个DOM树。根据节点与节点之间的关系来解析XML。适用于小文件的解析,大文件用DOM解析会照成资源占用过大。
/***
* 利用DOM 解析student.xml
*
*/
public class MyDomTest {
public static void main(String[] args) throws Exception{
//创建一个工厂
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
//创建对象
DocumentBuilder db=dbf.newDocumentBuilder();
//加载xml文件
Document document=db.parse("students.xml");
//获取student节点的集合
NodeList nodeList=document.getElementsByTagName("student");
System.out.println("共有学生"+nodeList.getLength()+"人");
//遍历student节点集合
for(int i=0;i<nodeList.getLength();i++) {
System.out.println("----------第"+(i+1)+"个学生的信息----------");
//通过item方法返回集合中的第i个项
Node node=nodeList.item(i);
//获取当前节点的属性集合
NamedNodeMap attrs=node.getAttributes();
for(int j=0;j<attrs.getLength();j++) {
Node a=attrs.item(j);
System.out.println("属性:"+a.getNodeName()+"\t值:"+a.getNodeValue());
}
//解析student的子节点
NodeList childNode=node.getChildNodes();
//遍历子节点
for(int k=0;k<childNode.getLength();k++) {
if (childNode.item(k).getNodeType()==Node.ELEMENT_NODE) {
System.out.print("节点名:"+childNode.item(k).getNodeName());
System.out.print("\t值:"+childNode.item(k).getFirstChild().getNodeValue()+"\n");
}
}
}
System.out.println("解析结束");
}
}
解析结果: