【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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
2
3
4
5
6
7
8
优缺点:
- 解析速度快,内存占用少
- 只支持对 XML 文件的读取,不支持写入
- 需要下载 jar 包下载链接 (opens new window)