- Jaxp介绍
是开发包,
- 获得jaxp中dom解析器的步骤
- ★java 解析xml 【dom技术】 看原理:
- xml文件也看成一颗dom树,在内存里面是存在的
- Dom特别适合做crud操作
- 由于加载到内存,所以不太适合操作比较大的文件
- <foot>叫元素、标签、节点(叫节点,往往是加载到内存里面去了)
- dom会将xml 中每一个元素、属性、文本,都映射成对应node对象/element对象
- ★★★属性通过getattribute()获取,从这个角度讲他不是node 节点,但从整体原理图的角度看,他又是的
- node是element的父接口,element接口里面的方法比较丰富一些
- 这几个是总纲,如果不明白的话,后面会一直很晕
- ★经典案例
- eclipse比较聪明,看到文件中声明的编码是utf-8,就会保存为utf-8格式
- eclipse看编码格式,右击,看properties
- document可以看成是一个单独的对象,也可以看成是一个根节点
我们讲一个快速入门案例:
<?xml version="1.0" ?>
<班级>
<学生>
<名字 sex=”男”>周星驰</名字>
<年龄>23</年龄>
<介绍>学习刻苦</介绍>
</学生>
<学生>
<名字>林青霞</名字>
<年龄>32</年龄>
<介绍>是一个好学生</介绍>
</学生>
</班级>
代码:
package two;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Test {
要记得查文档
//使用dom技术对xml文件进行crud操作
public static void main(String args[])throws Exception{
//创建一个DocumentBuilderFactory
得到创建解析器的工厂
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
//通过DocumentBuilderFactory,得到一个DocumentBuilder对象
得到一个解析器对象
DocumentBuilder dBuilder=dbf.newDocumentBuilder();
//指定解析那个xml文件
就得到了内存中的document
Document是一套接口
这里是绝对路径
Document document=dBuilder.parse("src/two/class.xml");
- 调用下面的具体方法
- 就是相当于将document节点给他了,就相当于将根节点取出来了
- 在类内部去调用方法,直接调用方法名就可以了
//add(document);
//del(document);
upd(document);
//read(document);
//list(document);
}
- 增加一个学生到xml中
- 程序本身根本就是不关心格式
- 格式只有程序员会看
- 换行会读取出#text
public static void add(Document doc)throws Exception{
//创建节点
Element newStu=doc.createElement("学生");
//添加一个属性值
第一个参数是属性名,第二个参数是属性值
newStu.setAttribute("sex", "男");
Element newStu_name=doc.createElement("名字");
newStu_name.setTextContent("小明2");
Element newStu_age=doc.createElement("年龄");
newStu_age.setTextContent("34");
Element newStu_intro=doc.createElement("介绍");
newStu_intro.setTextContent("这是一个好孩子");
newStu.appendChild(newStu_name);
newStu.appendChild(newStu_age);
newStu.appendChild(newStu_intro);
//把新的学生节点添加到根元素
获取根元素:
doc.getDocumentElement().appendChild(newStu);
//更新,不然添加的数据只能出现在内存中,在文件中没有更改
//得到TransformerFactory
这是一个工厂对象
TransformerFactory tff=TransformerFactory.newInstance();
//通过TransformerFactory得到一个转换器
Transformer tf=tff.newTransformer();
- transform方法进行转换
- 将原树转换成结果树
- 第一个参数是源
- 对文件进行覆盖,如果有文件,就进行覆盖,如果没有,创建一个新的
tf.transform(new DOMSource(doc), new StreamResult("src/two/class.xml"));
}
- 删除一个元素(如:小明2,学生)
- 如果删除不知道是哪一个的话
- 必须要遍历,不然没法解决
- 程序只要涉及删除修改和查找都会慢,因为他们都需要遍历
public static void del(Document doc)throws Exception{
首先找到这个学生
- 删除节点,
- 需要找到父节点
//Node node=doc.getElementsByTagName("学生").item(0);
//node.getParentNode().removeChild(node);
删除学生的sex属性
Xml 的属性是不能重复的
Element node=(Element)doc.getElementsByTagName("学生").item(0);
node.removeAttribute("sex");
//更新xml
//得到TransformerFactory
TransformerFactory tff=TransformerFactory.newInstance();
//通过TransformerFactory得到一个转换器
Transformer tf=tff.newTransformer();
tf.transform(new DOMSource(doc), new StreamResult("src/two/class.xml"));
}
- 修改操作
public static void upd(Document doc)throws Exception{
//找到
Element node=(Element)doc.getElementsByTagName("学生").item(0);
Element node_name=(Element)node.getElementsByTagName("名字").item(0);
修改文本节点
node_name.setTextContent("宋江");
修改属性节点
//node_name.setAttribute("sex", "男");
//更新xml
//得到TransformerFactory
TransformerFactory tff=TransformerFactory.newInstance();
//通过TransformerFactory得到一个转换器
Transformer tf=tff.newTransformer();
tf.transform(new DOMSource(doc), new StreamResult("src/two/class.xml"));
}
}
- 查询指定学生信息
- 使用dom去遍历xml文件和指定获取某个节点
- 具体地查询某个学生的信息(显示第一个学生的所有信息)
- 请考虑如何获取某个元素的属性值(取出)
- 这种方式无论xml写的再乱,也不N会出错
public static void read(Document doc){
- 如果有id 就直接可以getELementById()
- 返回的是list集合
- 因为处于目标的上层,所以能获得
NodeList n1=doc.getElementsByTagName("学生");
- //取出第一个学生
- Node 是父接口
- element是子接口,方法多
Element stu=(Element)n1.item(0);
通过这种方式获取属性
System.out.println("学生的性别是"+stu.getAttribute("sex"));
同样的标签可以出现多次
经过试验
Element name=(Element)stu.getElementsByTagName("年龄").item(0);
System.out.println(name.getTextContent());
System.out.println("发现"+n1.getLength()+"个学生");
}
- 遍历该xml文件
document也可以看成一个接口
关联 聚合 组合
public static void list(Node node){
- Node 有类型的,有实体,有元素、注释、文本、文档、指令节点
- 判断类型,只要元素节点
if(node.getNodeType()==node.ELEMENT_NODE){
System.out.println("名字:"+node.getNodeName());
}
//System.out.println("名字:"+node.getNodeName());
//取出node的子节点
NodeList nodeList=node.getChildNodes();
for(int i=0;i<nodeList.getLength();i++){
//再去显示
Item代表当前list中第几个
Node n=nodeList.item(i);
System.out.println(n.getNodeName());
- 遍历,
- 遍历不用递归,根本搞不定
- 因为是面向对象
list(n);
}
}