-
jaxp进行sax解析
dom解析:一次性读到内存,占用内存比较大
sax解析:sax的出现就是为了弥补dom解析的缺陷(内存消耗大),sax解析内存消耗小。 读取一部分,解析一部分
sax: Simple Api(for) Xml,来自于开源社区,已经纳入了javase的规范
sax的api在jdk: org.xml.sax.*
sax解析原理: 读到xml文档的某部分内容,就会触发对应的事件处理代码。
package gz.itcast.a_sax;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
//演示sax解析原理
public class Demo1 {
/**
* @param args
* @throws SAXException
* @throws ParserConfigurationException
*/
public static void main(String[] args) throws Exception {
//1)创建SAXParseFactory对象
SAXParserFactory factory = SAXParserFactory.newInstance();
//2)创建SAXParser对象
SAXParser sp = factory.newSAXParser();
//3)得到一个xmlreader
XMLReader reader = sp.getXMLReader();
//4)xmlreader绑定事件监听器
reader.setContentHandler(new MyContentHandler());
//5)开始读取
reader.parse("src/exam.xml");
}
}
class MyContentHandler implements ContentHandler{
@Override
public void endPrefixMapping(String prefix) throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void processingInstruction(String target, String data)
throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void setDocumentLocator(Locator locator) {
// TODO Auto-generated method stub
}
@Override
public void skippedEntity(String name) throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void startDocument() throws SAXException {
System.out.println("读取到了文档开始");
}
/**
* @param qName: 表示元素名称
* @param atts : 属性列表(属性包含在开始元素)
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
System.out.println("读取到了元素开始:"+qName);
}
/**
* @param ch: 表示到目前为止读到的所有文本内容的数组
* @param start: 表示当前读到的文本所处的位置(下标)
* @param length: 表示当前读到的文本内容的长度
* xxxxxxxxx张三
* 20 22
* ch: 22
* start:20
* length 2
* 读到当前的文本内容
* new String(ch,start,length) : 张三
*/
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println("读取到了文本内容:"+new String(ch,start,length));
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("读取到了元素结束:"+qName);
}
@Override
public void endDocument() throws SAXException {
System.out.println("读取到了文档结束");
}
@Override
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
}
}
案例:
1)读取xml指定内容
2)读取xml内容,封装成对象。
sax核心的api:
1)创建SAXParserFactory对象
2)通过SAXParserFactory对象得到SAXParser对象
3)通过SAXParser对象得到XMLReader解析器
4)在XMLReader解析器注册事件监听器(ContentHandlder接口)
5) 使用XMLReader的parse方法进行读取xml文件
ContentHandlder接口常用方法
startDocument(): 文档开始触发
startElement(): 读到元素开始触发
characters(): 读到文本内容触发
endElement(): 读到元素结束触发
endDocument(): 读到文档结束触发
-
Junit单元测试
开发步骤:
1)建立一个Junit Test Case的类
2)直接在每个方法中写测试逻辑
3)运行测试方法
写Junit的测试方法
1)方法顶部一定要加上@Test注解
2)方法必须是public修饰,不能有返回值,不能有参数,可以抛出异常
查看Junit的测试结果
看junit导航条
绿色: 代表测试通过
红色: 代表测试不通过
运行junit测试方法
1)双击方法,右键“junit test”运行。(运行一个方法)
2) 双击类,右键“junit test”运行。(运行类中多个方法)
3)双击项目,右键“junit test”运行。(运行项目中多个方法)
判断结果
Assert类:
assertEquals()
assertSame()
assertTrue()
assertFalse()
五个常用注解
@Test
@Before
@After
@BeforeClass
@AfterClass
MathUtil
package gz.itcast.b_junit;
//数学工具类
public class MathUtil {
/**
* 加法运算
* @param a
* @param b
* @return
*/
public static int add(int a,int b){
return a+b;
}
/**
* 除法运算
* @param a
* @param b
* @return
*/
public static int div(int a,int b){
return a%b;
}
public static void print(){
System.out.println("print-=====");
boolean flag = false;
if(flag){
throw new RuntimeException("方法内部的异常");
}
}
}
TestMathUtil
package gz.itcast.b_junit;
import junit.framework.Assert;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
// 测试MathUtil
public class TestMathUtil {
//这个方法需要在每个测试方法之前执行的话,可以加上一个注解@Before
//@Before
//如果说要在所有的测试方法之前只执行1次,可以给这个方法加上@BeforeClass(必须是static)
@BeforeClass
public static void init(){
System.out.println("初始化代码");
}
//这个方法需要在每个测试方法之后执行的话,可以加上@After
//@After
//如果说要在所有的测试方法之后只执行1次,可以给这个方法加上@AfterClass(必须是static)
@AfterClass
public static void destory(){
System.out.println("清理代码");
}
@Test
public void testAdd()throws Exception {
//System.out.println("===");
int result = MathUtil.add(10, 20);
/*if(result!=30){
throw new RuntimeException("结果错误");
}*/
//使用junit的专业的结果判定的方法
// Assert工具类: 断言类。用来判定结果
//Assert.assertEquals(30, result); //相等:测试通过;不相等:测试不通过;
//Assert.assertTrue(true); //true:测试通过;false:测试不通过;
//Assert.assertFalse(false); //false:测试通过;true:测试不通过;
Cat c1 = new Cat("tom",2);
Cat c2 = new Cat("tom",2);
//Assert.assertSame(c1, c2);// 使用==进行比较。
Assert.assertEquals(c1, c2);//使用equals方法进行比较
}
@Test
public void testDiv() {
//System.out.println("!!!!!");
int result = MathUtil.div(20, 10);
if(result!=2){
throw new RuntimeException("结果错误");
}
}
@Test
public void testPrint() {
MathUtil.print();
}
}
class Cat{
private String name;
private int age;
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 Cat(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Cat other = (Cat) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
-
DOM4J基本使用
dom4j:用过jaxp,使用dom4j可以更加简单地操作xml(也是基于dom解析原理的工具)
1)读取xml文件:
//1)创建SAXReader对象
SAXReader reader = new SAXReader();
//2)读取xml文件
Document doc = reader.read(“src/exam.xml”);
查询:
元素相关的:
element(“name”)
elements(“name”);
…
属性相关的:
attribute(“name”)
attributeValue(“name”)
…
文本相关的:
getText()
2)写出xml文件
//1)创建一个XMLWriter对象
XMLWriter writer = new XMLWriter(
new FileOutputStream(“src/exam.xml”));
//2)写出xml文件
writer.write(doc);
//3)关闭流
writer.close();
创建或修改:
addElement(“name”) 添加元素
addAttribute(“name”,“value”);// 添加属性
setText(“value”) 添加文本
删除:
detach()
getParent().remove(elem);
XML文件
<?xml version="1.0" encoding="UTF-8"?>
<exam>
<student examid="222" idcard="111">
<name>张三</name>
<location>沈阳</location>
<grade>89</grade>
</student>
<student idcard="333">
<name>李四</name>
<location>大连</location>
<grade>97</grade>
</student>
<location>小连</location>
</exam>
学习dom4j的基本使用
package gz.itcast.c_dom4j;
import java.io.FileOutputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
// 目标: 学习dom4j的基本使用
public class Demo1 {
Document doc = null;
@Before
public void init() throws Exception{
//1)创建SAXReader对象
SAXReader reader = new SAXReader();
//2)读取xml文件
doc = reader.read("src/exam.xml");
}
@After
public void write2xml() throws Exception{
//写出到xml文件中
//1)创建一个XMLWriter对象
XMLWriter writer = new XMLWriter(
new FileOutputStream("src/exam.xml"));
//2)写出xml文件
writer.write(doc);
//3)关闭流
writer.close();
}
//读取xml文件
@Test
public void test1() throws Exception{
//1)创建SAXReader对象
SAXReader reader = new SAXReader();
//2)读取xml文件
Document doc = reader.read("src/exam.xml");
System.out.println(doc);
}
//查找节点:
// 元素 / 属性 / 文本
// 元素:第二个 <location>
@Test
public void test2(){
//1)根元素
Element root = doc.getRootElement();
System.out.println(root.getName());
//注意:dom4j的优势在于操作的api都是符合常用的标准(例如集合.java.uitl.*)
List list = root.elements("student");//exam下的所有student元素
//方式一:
/*for(int i=0;i<list.size();i++){
list.get(i);
}*/
//方式二:
/*for(Object obj:list){
}*/
//方式三: 迭代器 hasNext() 判断是否有下一个元素 next(): 取出下一个元素
/*Iterator it = list.iterator();
while(it.hasNext()){
it.next();
}*/
Element stuElem = (Element)list.get(1);
Element locElem = stuElem.element("location");// 在student元素下查询一个指定名称的元素
System.out.println(locElem);
System.out.println(stuElem.attribute("examid").getValue());//查询属性值
System.out.println(stuElem.attributeValue("examid"));//查询属性值
System.out.println(locElem.getText());//文本内容
}
//创建或修改:
// 元素 、 属性 、 文本
@Test
public void test3() throws Exception{
//1)创建<student>
Element root = doc.getRootElement();
Element stuElem = root.addElement("student");
//2)在新的<student>再新建一个examid和idcard属性
stuElem.addAttribute("examid", "555");
stuElem.addAttribute("idcard", "666");
//3)在<student>下新建立一个<name>
Element nameElem = stuElem.addElement("name");
//4)设置<name>的文本内容为“王五”
nameElem.setText("王五");
}
//删除节点:
// 元素 、 属性
@Test
public void test4(){
//Element stuElem = (Element)doc.getRootElement().elements("student").get(2);
//stuElem.detach();//自杀
//stuElem.getParent().remove(stuElem);//它杀
Element stuElem = (Element)doc.getRootElement().elements("student").get(1);
stuElem.attribute("examid").detach();
}
//学习xpath的基本使用(回去查询xpath文档学习)
@Test
public void test5(){
//需求: 删除第二个<grade>
// 1)快速找到<grade>
Element gElem = (Element)doc.selectSingleNode("//student[2]");
//gElem.detach();
//2) 找第二个<location>
//List nodes = doc.selectNodes("//location[1]");
// 找examid属性值为222的student
List nodes = doc.selectNodes("//student[@examid='222']");
for (Object object : nodes) {
System.out.println(object);
}
}
}
-
xpath基本使用
遇到了xml的层次结构非常深的时候,使用dom4j获取时很麻烦的!!这时就可以使用xpath。
核心的方法:
List list = document.selectNodes( “//foo/bar” ); 查询多个节点
Node node = document.selectSingleNode( “//foo/bar/author” ); 查询一个节点
xpath的常用语法:
/ 代表根(从根开始找)
// 所有子节点(不分层次)
-
schema约束
链接:https://www.w3school.com.cn/schema/schema_simple.asp
目标: 能够看着scheme约束来学有效的xml文件
重点:使用名称空间导入schema文件
第一步:找到schema的名称空间,在xml文件中定义这个名称空间,给该名称给短名称
第二步:在xml文件中定义名称空间对应的schema文件地址
第三步:定义一个xsi的名称空间,w3c组织的标准名称空间
<itcast:书架 xmlns:itcast=“http://www.itcast.cn”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=“http://www.itcast.cn book.xsd”>
总结需要掌握的内容:
会写一个XML,会读取XML,语法:元素定义、属性定义、文档声明; 约束:DTD约束/Schema约束
公用组件:
struts, DTD约束
hibernate, DTD约束
Spring, Schema约束
DOM解析
sun公司定义的统一技术规范
DOM4J 解析技术
SAX解析
sun公司定义的技术