【JAVA】:XML解析模型(完整版)

2020/6/8 Java

# 解析 XML(完整版)

# 一、DOM 解析

创建 xml 文件

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<person>
     <p1>
        <name>zhangsan</name>
        <age>20</age>
     </p1>
     <p1>
         <name>lisi</name>
         <age>12</age>
     </p1>
</person>
1
2
3
4
5
6
7
8
9
10
11

实例一:解析 xml 文件中所有标签 name 的值和第一个标签 name 的值

	public static void demo1()throws Exception{
//    	创建解析器工厂
		DocumentBuilderFactory builderfactory=DocumentBuilderFactory.newInstance();
//		创建解析器
		DocumentBuilder builder=builderfactory.newDocumentBuilder();
//		解析xml返回document
		Document document=builder.parse("src/Person.xml");
//		得到name元素
		NodeList list=document.getElementsByTagName("name");
//		遍历list
		for(int i=0;i<list.getLength();i++){
			Node node=list.item(i);//得到每一个name的标签
//			得到文本内容
			String s=node.getTextContent();
			System.out.println(s);
		}
//		得到第一个name标签文本内容
		Node nod=list.item(0);
		String s1=nod.getTextContent();
		System.out.println(s1);
	}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

在这里插入图片描述

实例二:在第一个 p1 标签内添加 sex 标签

public static void addsex() throws Exception{
		DocumentBuilderFactory builderfactory=DocumentBuilderFactory.newInstance();
		DocumentBuilder builder=builderfactory.newDocumentBuilder();
		Document document=builder.parse("src/Person.xml");
//		得到所有标签p1
		NodeList list=document.getElementsByTagName("p1");
//		获取第一个p1
		Node p1node=list.item(0);
//		创建<sex>标签
		Element sex=document.createElement("sex");
//		创建文本内容
		Text text=document.createTextNode("男");
//		把文本添加到标签<sex>内
		sex.appendChild(text);
//		将标签添加到<p1>下面
		p1node.appendChild(sex);
//		回写xml(直接复制代码即可)
		TransformerFactory transformerFactory=TransformerFactory.newInstance();
		Transformer transformer=transformerFactory.newTransformer();
		transformer.transform(new DOMSource(document),new StreamResult("src/Person.xml"));
	}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

在这里插入图片描述

实例三:修改标签内的文本内容 sex

	public static void updatesex() throws Exception{
		DocumentBuilderFactory builderfactory=DocumentBuilderFactory.newInstance();
		DocumentBuilder builder=builderfactory.newDocumentBuilder();
		Document document=builder.parse("src/Person.xml");
		Node sex=document.getElementsByTagName("sex").item(0);
//		修改sex文本值
		sex.setTextContent("nan");
//		回写xml(直接复制代码即可)
		TransformerFactory transformerFactory=TransformerFactory.newInstance();
		Transformer transformer=transformerFactory.newTransformer();
		transformer.transform(new DOMSource(document),new StreamResult("src/Person.xml"));
	}
1
2
3
4
5
6
7
8
9
10
11
12

在这里插入图片描述

实例四:删除标签 sex。

	public static void deletesex()throws Exception{
		DocumentBuilderFactory builderfactory=DocumentBuilderFactory.newInstance();
		DocumentBuilder builder=builderfactory.newDocumentBuilder();
		Document document=builder.parse("src/Person.xml");
		Node sex=document.getElementsByTagName("sex").item(0);
//		得到sex的父节点
		Node p1=sex.getParentNode();
//		删除sex
		p1.removeChild(sex);
//		回写xml(直接复制代码即可)
		TransformerFactory transformerFactory=TransformerFactory.newInstance();
		Transformer transformer=transformerFactory.newTransformer();
		transformer.transform(new DOMSource(document),new StreamResult("src/Person.xml"));
	}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

在这里插入图片描述 优缺点:

  • 采用树型结构
  • 将所有标签封装成对象
  • 优点:适合对标签进行增删查改
  • 缺点:会导致内存溢出

# 二、SAX 解析

创建 xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<person>
    <p1>
        <name>zhangsan</name>
        <age>20</age>

     </p1>
     <p1>
         <name>lisi</name>
         <age>12</age>
     </p1>
</person>
1
2
3
4
5
6
7
8
9
10
11
12

实例一:打印 xml 文件标签

class MyDefault extends DefaultHandler{
	@Override
	public void startElement(String uri, String localname, String qName,
			Attributes arg3) throws SAXException {
		System.out.print("<"+qName+">");//打印头标签
	}
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		System.out.print(new String(ch,start,length));//打印文本内容
	}
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		System.out.print("</"+qName+">");//打印尾标签
	}
}

//测试
	public static void main(String[] args) throws Exception{
//		创建解析工厂
		SAXParserFactory saxparaserfactory=SAXParserFactory.newInstance();
//		创建解析器
		SAXParser saxparser=saxparaserfactory.newSAXParser();
//		执行parser方法
		saxparser.parse("Person.xml", new MyDefault());
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

在这里插入图片描述

实例二:打印 name 标签

class MyDefault1 extends DefaultHandler{
	boolean flag=false;
	@Override
	public void startElement(String uri, String localname, String qName,
			Attributes arg3) throws SAXException {
		//判断是否为name
		if("name".equals(qName)){
			flag=true;
			}
	}
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		//如果flag的值为true
		if(flag==true){
			System.out.println(new String(ch,start,length));
		}
	}
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if("name".equals(qName)){
			flag=false;
		}
	}
}
//测试
public class TextJaxp {
	public static void main(String[] args) throws Exception{
//		创建解析工厂
		SAXParserFactory saxparaserfactory=SAXParserFactory.newInstance();
//		创建解析器
		SAXParser saxparser=saxparaserfactory.newSAXParser();
//		执行parser方法
		saxparser.parse("Person.xml", new MyDefault1());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

在这里插入图片描述

实例三:打印第一个 name 标签

class MyDefault2 extends DefaultHandler{
	boolean flag=false;
	int index=1;
	@Override
	public void startElement(String uri, String localname, String qName,
			Attributes arg3) throws SAXException {
		//判断是否为name
		if("name".equals(qName)){
			flag=true;
			}
	}
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		// TODO Auto-generated method stub
		//如果flag的值为true
		if(flag==true&&index==1){
			System.out.println(new String(ch,start,length));
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if("name".equals(qName)){
			flag=false;
			index++;
		}
	}
}
//测试
public class TextJaxp {
	public static void main(String[] args) throws Exception{
//		创建解析工厂
		SAXParserFactory saxparaserfactory=SAXParserFactory.newInstance();
//		创建解析器
		SAXParser saxparser=saxparaserfactory.newSAXParser();
//		执行parser方法
		saxparser.parse("Person.xml", new MyDefault2());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

在这里插入图片描述 注意:       事件处理类需要继承 DefaultHandler 且需要覆写 startElement()characters()endElement()顺序不能改变。

优缺点:

  • 不能进行对 xml 的标签进行增删查改,只能查询
  • 不会造成内存溢出
  • 采用边读边解析 (事件处理)

# 三、DOM4j 解析

创建 XML 文件

<?xml version="1.0" encoding="UTF-8"?>
<person>
  <p1 id="aaaa">
    <name>zhangsan</name>
    <school>dax</school>
    <age>20</age>
    <nev>nan</nev>
  </p1>
  <p1>
    <name>lisi</name>
    <age>12</age>
  </p1>
</person>
1
2
3
4
5
6
7
8
9
10
11
12
13

实例一:查询 xml 下的所有 name 值

     public static void select() throws Exception{
//    	 创建解析器
    	 SAXReader saxreader=new SAXReader();
//    	 返回document
    	 Document document=saxreader.read("src/Person.xml");
//    	 得到根结点
    	 Element root=document.getRootElement();
//    	 得到p1
    	 List<Element>list=root.elements("p1");
//       遍历p1
    	 for(Element element:list){
    		 Element name=element.element("name");
    		 System.out.println(name.getText());
    	 }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

在这里插入图片描述

实例二:查询 xml 下的所有 name 值(XPath 表达式)

public static void selectx() throws Exception{
    	 SAXReader saxreader=new SAXReader();
    	 Document document=saxreader.read("src/Person.xml");
    	 List<Node> list=document.selectNodes("//name");
    	 for(Node node:list){
    		 System.out.println(node.getText());
    	 }
     }
1
2
3
4
5
6
7
8

在这里插入图片描述

实例三:获取第一个 p1 下的 name 值

public static void select_firstname() throws Exception{
    	 SAXReader saxreader=new SAXReader();
    	 Document document=saxreader.read("src/Person.xml");
    	 Element root=document.getRootElement();
//    	 得到第一个p1
    	 Element p1=root.element("p1");
//    	 得到p1下的name
    	 Element name=p1.element("name");
    	 System.out.println(name.getText());
    }
1
2
3
4
5
6
7
8
9
10

在这里插入图片描述 实例三:在第一个 p1 标签下添加标签 nev

public static void addnev() throws Exception{
    	 SAXReader saxreader=new SAXReader();
    	 Document document=saxreader.read("src/Person.xml");
    	 Element root=document.getRootElement();
//    	 得到第一个p1
    	 Element p1=root.element("p1");
//    	 在p1下添加<nev>
    	 Element nev=p1.addElement("nev");
//    	 添加文本
    	 nev.addText("nan");
//    	 回写xml
    	 OutputFormat format=OutputFormat.createPrettyPrint();//格式化
//    	 OutPutFormat format=OutputFormat.createCompactFormat();压缩
    	 XMLWriter xmlwriter=new XMLWriter(new FileOutputStream("src/Person.xml"),format);
    	 xmlwriter.write(document);
    	 xmlwriter.close();
     }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

在这里插入图片描述 实例四:在特定位置添加标签(在第一个 p1 下的 age 之前添加 school)

 public static void addschool() throws Exception{
    	 SAXReader saxreader=new SAXReader();
    	 Document document=saxreader.read("src/Person.xml");
    	 Element root=document.getRootElement();
//    	 得到第一个p1
    	 Element p1=root.element("p1");
//    	 获取p1下所有标签
    	 List<Element>list=p1.elements();
//    	 创建标签
    	 Element school=DocumentHelper.createElement("school");
    	 school.setText("dax");
//    	 在特定位置添加
    	 list.add(1,school);
//    	 回写xml
    	 OutputFormat format=OutputFormat.createPrettyPrint();
    	 XMLWriter xmlwriter=new XMLWriter(new FileOutputStream("src/Person.xml"),format);
    	 xmlwriter.write(document);
    	 xmlwriter.close();
     }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

在这里插入图片描述

实例五:获取标签属性值

public static void select_Value() throws Exception{
    	 SAXReader saxreader=new SAXReader();
    	 Document document=saxreader.read("src/Person.xml");
    	 Element root=document.getRootElement();
//    	 得到第一个p1
    	 Element p1=root.element("p1");
    	 System.out.println(p1.attributeValue("id"));
     }
1
2
3
4
5
6
7
8

在这里插入图片描述 优缺点: