【JavaWeb笔记】XML、XPath

1 篇文章 0 订阅
1 篇文章 0 订阅

XML

W3C( 万维网联盟 )先定义出来的是HTML ,XML推出初衷是为了替换HTML ,因为HTML语法太过松散, XML规定非常严格。 
XML 用做配置文件 封装数据
HTML:超文本标记语言 定义网页元素



1.概念:   

可扩展标记语言,标签名可以自己定义  <student></student> 

命名规范:不能用数字开头,不能使用纯数字,区分大小写 。  


2. 功能:  

a.用作配置文件 ;  

b.用作网络数据传输的载体,xml 用于PC端数据传输的载体,JSON {"username":"张三","age":23,"sex":"1"} 一般用于移动端的数据传输载体,因为体积小。  


3. 语法: 

新建一个文本文件 后缀名必须为 .xml 


4. 组成部分:  

文档声明:<?xml version="1.0" encoding="utf-8"?>     

 endoing  告诉浏览用什么编码去解析  

文档声明:必须顶行写,还有顶格写。  

根标签:有且仅有一个根标签  其他标签 有开始标签 一定要有结束标签  


5. 文本: 

CDATA区:该区域的文本,会按照纯文本解析 

格式: <![CDATA[ 内容 ]]>  

处理指令: <?xml-stylesheet type="text/css" href="1.css"?>


6.解析XML

 a. DOM: Document Object Model 文档对象模型,将文档的各个组成部分抽取一个对象
Element
     标签对象
Attribute
    属性对象
Text  文本对象
Comment
   注释对象
Node
          节点对象
Document
   文档对象
解析:将文档一次性 加载进内存 然后将文档各个组成不封抽取为对象
优点: 能够对文档进行增删改查
缺点:耗内存 适用于PC 端


b. SAX :基于事件 逐行解析,一次读取一行,释放一行
优点 :不占内存  适用于移动端;
缺点:只能查 不能增删改.


7. 常用的XML解析器

DOM4J第三方jar包实现了DOM思想
Pull解析器:第三方jar包
实现了SAX思想


8. 主要方法

a.修改xml文件

1)先把xml文件文件读进内存,

2) 找到你要修改的节点,去修改;

setText(); 设置文本

3)再写入硬盘 覆盖掉源文件.

b. 删除xml属性/标签

detach();删除标签/属性

c. 修改文本 

setText();设置文本

d. 写入硬盘覆盖原文件

//设置格式,二选一,默认紧凑格式
OutputFormat format = OutputFormat.createCompactFormat();// 紧凑的格式
OutputFormat prettyPrint = OutputFormat.createPrettyPrint();//漂亮格式
//覆盖原文件
XMLWriter writer = new XMLWriter(new FileOutputStream("students.xml"), format);
		writer.write(doc);
		writer.close();


------------------------------------------------------------------------------------


DOM4J解析器

1.获取节点对象的主要方法

 	// 创建解析器对象  
        SAXReader reader = new SAXReader();    
        // 加载xml文件  
        Document doc = reader.read(new FileInputStream("students.xml")); 

	//获取节点标签,只能获取一个子节点
	Node node = doc.node(0);


 	// 获取根标签对象 getRootElement();  
        Element rootElement = doc.getRootElement();

	// 获取根标签下的子标签 默认获取的是第一个子标签
	Element stuElement = rootElement.element("student");

	// 通过集合获取所有的子标签
	List<Element> eles = rootElement.elements();
		for (Element ele : eles) {
		System.out.println(ele.getName());
		}


	//通过迭代器获取所有子标签
	Iterator<Element> elementIterator = rootElement.elementIterator();
		while (elementIterator.hasNext()) {
			Element element = elementIterator.next();
			System.out.println(element.getName());

		}


	// 获取所有的节点
	Iterator<Node> iterator = doc.nodeIterator();
		 while (iterator.hasNext()) {
		 Node nodes = iterator.next();
		 System.out.println(nodes.getName());
		
		 }

2.获取属性对象的相关方法

	//获取属性对象
	Element element = rootElement.element("student");
	//获取id属性
	Attribute attribute = element.attribute("id");
	//获得属性值
	String value = attribute.getValue();
	//获取属性名
	String name = attribute.getName();

	// 直接获取属性值
	String value2 = rootElement.element("student").attributeValue("id");


	// 获取所有的属性对象
	List<Attribute> attributes = rootElement.element("student").attributes();
		for (Attribute atr : attributes) {
			String name2 = atr.getName();
			String value3 = atr.getValue();
			System.out.println(name2 + "======" + value3);

		}

	//通过迭代器获取所有属性对象
	Iterator<Attribute> attributeIterator = rootElement.element("student").attributeIterator();
		while(attributeIterator.hasNext()){
			Attribute attribute2 = attributeIterator.next();
			System.out.println(attribute2.getName()+"=="+attribute2.getValue());
			
		}

3.获取标签之间的文本

	//方式1
	String text = doc.getRootElement().element("student").element("name").getText();
		
	//方式2
	String text2 = doc.getRootElement().element("student").elementText("name");

4.封装XML

代码实现如下,student.xml和Student对象类省略不写:

package org.xxxx.xml;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Iterator;



import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import bean.Student;

public class XmlDemo {
	public static void main(String[] args) throws FileNotFoundException, DocumentException {
		ArrayList<Student> arr=new ArrayList<>();
		//创建解析器对象
		SAXReader reader=new SAXReader();
		//读取xml文件
		Document doc=reader.read(new FileInputStream("students.xml"));
		//获取根标签
		Element rootElement = doc.getRootElement();
		//获取所有子标签
		Iterator<Element> iterator = rootElement.elementIterator();
		//遍历封装
		while(iterator.hasNext()){
			Element element = iterator.next();
			//
			String id = element.attributeValue("id");
			String name = element.elementText("name");
			String age = element.elementText("age");
			String tel = element.elementText("tel");
			Student stu=new Student(id, name, age, tel);
			arr.add(stu);
		}
		System.out.println(arr);
	}

}

------------------------------------------------------------------------------------

Pull解析器

序列化与反序列化

将students.xml文件先反序列化到内存中,再序列化到stu.xml中。


package org.xxxx.xml;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;

import bean.Student;

public class PullDemo {
	private static ArrayList<Student> list;
	private static Student student; 
	public static void main(String[] args) throws XmlPullParserException, IOException {
		//获取解析器工厂对象
		XmlPullParserFactory factory =XmlPullParserFactory.newInstance();
		//从工厂里获取解析对象
		XmlPullParser parser = factory.newPullParser();
		//关联xml文件
		parser.setInput(new FileInputStream("students.xml"), "utf-8");
		//获取事件类型
		int type=parser.getEventType();
		while(type!=XmlPullParser.END_DOCUMENT){
			String name = parser.getName();
			switch(type){
			case XmlPullParser.START_TAG:
				if("students".equals(name)){
					 list = new ArrayList<Student>();
					 
				}else if("student".equals(name)){
					student=new Student();
					String id = parser.getAttributeValue(0);
					student.setId(id);
					
				}else if("name".equals(name)){
					String text = parser.nextText();
					student.setName(text);
					
				}else if("age".equals(name)){
					String age = parser.nextText();
					student.setAge(age);
				
				}else if("tel".equals(name)){
					String tel = parser.nextText();
					student.setTel(tel);
				
				}
				break;
				
			case XmlPullParser.END_TAG:
				if("student".equals(name)){
					list.add(student);
				}
				break;
				
			}
			//指针指向下一行
			type=parser.next();
		}
		System.out.println(list);
		//抽取一个方法,进行序列化
		saveDataToXML(factory);
	}
	
	private static void saveDataToXML(XmlPullParserFactory factory) throws XmlPullParserException, IllegalArgumentException, IllegalStateException, FileNotFoundException, IOException {
		//获取序列化器
		XmlSerializer serializer = factory.newSerializer();
		//设置输出流关联xml文件
		serializer.setOutput(new FileOutputStream("stu.xml"), "utf-8");
		//写入文档声明
		serializer.startDocument("utf-8", true);
		//写入根标签
		serializer.startTag(null, "students");
		//循环写入
		for(Student s:list){
			//写入student标签
			serializer.startTag(null, "student");
			//写入属性
			serializer.attribute(null, "id", s.getId());
			//写入开始标签
			serializer.startTag(null, "name");
			//写入标签之间的文本
			serializer.text(s.getName());
			serializer.endTag(null, "name");
			serializer.startTag(null, "age");
			serializer.text(s.getAge());
			serializer.endTag(null, "age");
			serializer.startTag(null, "tel");
			serializer.text(s.getTel());
			serializer.endTag(null, "tel");
			serializer.endTag(null, "student");
		}
		serializer.endTag(null, "students");
		//写入文档结束事件
		serializer.endDocument();
	}

}

------------------------------------------------------------------------------------

XPath

1.概述

路径规则书写的一门技术,他的作用是用来快速找到 XML文档中的一个或多个标签;
 一般来说如果要找深层级的标签 那么使用xPath找起来非常快。


2.具体方法

a. 导入DOM4J的jar包和XPath的jar包;

b. 普通方法查找标签

 List<Element> elements = doc.getRootElement().elements();
 Element element = elements.get(1);
    XPath查找标签

String path = "//student[@id='s002']";
// selectSingleNode(path) 配合xPath 找到单个节点对象
Element selectSingleNode = (Element) doc.selectSingleNode(path);
// 找到根标签下的所有标签 selectNodes(path);配合xPath 找到多个节点
path = "//student";
List<Node> selectNodes = doc.selectNodes(path);
for (Node node : selectNodes) {
	System.out.println(node.getName());
		}

3.简单语法

 last() 选最后一个节点
 text() 文本
@ 定位一个属性名
* 统配符
 / 绝对路径 一级一级往下定位
 // 不分层级 相对定位
 and 并且
 not() 取反








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值