目录

 

一,什么是XML:

二,XML的解析


一,什么是XML:

定义:XML指的是可扩展标记语言,主要用来传输和存储数据。


XML主要语法规则:

XML标签需要用户自定义

XML标签使用时要关闭<标签名> </标签名>成对存在

XML标签对区分大小写

XML标签必须正确的嵌套

XML文档有且只有一个根元素

XML的属性值要加引号

XML中的空格换行符等会被当做内容读取



 

二,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;
    }
}

解析结果:

 

java hutool XmlUtil 如何解析 xml并获取标签的内容 java解析xml文件的标签内容_java

 


2.2 PULL解析

PULL解析与SAX解析方式相似,都是事件驱动方式。使用PULL解析需要导入的jar包。

jar包地址:

/**
 * 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();//获取下一个标签的类型
        }
    }
}

解析结果:

java hutool XmlUtil 如何解析 xml并获取标签的内容 java解析xml文件的标签内容_xml_02

 


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("解析结束");
	}
}

解析结果:

java hutool XmlUtil 如何解析 xml并获取标签的内容 java解析xml文件的标签内容_XML_03