xml的解析
背景知识
xml是标记型文档
js使用dom解析标记型文档
-根据html 的层级结构,在内存中分配一个树形结构,把html的标签,属性和文本都封装成对象
-document对象、element对象、属性对象、文本对象、Node节点对象
xml的解析方式(技术):dom和sax
dom
根据xml的层级结构,在内存中分配一个树形结构,把html的标签,树形和文本都封装成对象
缺点:使用dom方式解析xml时候,如果文件过大,造成内存溢出
优点:方便实现增删改操作
sax
采用事件驱动,边读边解析(从上到下,一行一行的解析,解析到某一个对象,把对象名称返回)
优点:使用sax方式不会造成内存溢出,实现查询
缺点:使用sax方式不能实现增删改操作
解析器
要想解析xml,首先需要解析器
不同的公司和组织提供了针对dom和sax方式的解析器,通过api方式提供
sun公司提供了jaxp
dom4j组织提供了dom4j
jdom组织提供了jdom
jaxp的api的查看
jaxp是javase的一部分
jaxp解析器在jdk的javax.xml.parsers包里面
四个类:分别是针对dom和sax解析使用的类
dom:DocumentBuilder :解析器类(抽象类)
此类的实例可以从DocumentBuilderFactory.newDocumentBuilder()方法获取
一个方法,可以解析xml parse("xml路径"),返回是Document整个文档
在document里面的方法:
getElementsByTagName(String),得到标签,返回集合NodeList
createElement(String):创建标签
createTextNode(String):创建文本
appendChild(Node):添加节点
removeChild(Node):删除节点
getParentNode():获取父节点
NodeList:getLength():得到集合长度
item():下标取到具体值,返回Node,之后通过getTextContent()得到标签内的值
DocumentBuilderFactory:解析器工厂(抽象类)
此类使用newInstance()创建
使用jaxp查询节点
操作步骤:1、创建解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
2、根据解析器工厂创建解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
3、解析xml返回document
Document document = builder.parse("src/person.xml");
4、得到所有的name元素(getLength,item)
for(int i =0;i<list.getLength();i++){
Node name1 = list.item(i);//得到每一个name元素}
5、返回集合,遍历集合,得到内容
String s =name1.getTextContent();
使用jaxp添加节点
操作步骤:1、创建解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
2、根据解析器工厂创建解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
3、解析xml返回document
Document document = builder.parse("src/person.xml");
4、得到要插入节点的上一个节点
5、创建标签
Elenent name = document.createElement("标签名");
6、创建文本
Text text = document.createTextNode("nv");
7、把文本添加到标签下面
name.appendChild(text1);
8、把name标签添加到获取的节点下面
节点.appendChild(name);
9、回写xml
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document),new StreamResult(文件路径"));
使用jaxp修改节点
操作步骤:1、创建解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
2、根据解析器工厂创建解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
3、解析xml返回document
Document document = builder.parse("src/person.xml");
4、得到节点 使用item方法
5、修改节点内的值 setTextContent方法
节点.setTextContent("内容");
6、回写xml
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document),new StreamResult(文件路径"));
使用jaxp删除节点
操作步骤:1、创建解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
2、根据解析器工厂创建解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
3、解析xml返回document
Document document = builder.parse("src/person.xml");
4、得到节点 使用item方法
5、得到节点的父节点,使用getParentNode()
6、使用父节点删除,使用removeChild(节点)
7、回写xml
使用jaxp遍历节点
1、创建解析器工厂
2、根据解析器工厂创建解析器
3、解析xml返回document
====使用递归实现====
4、得到根节点
5、得到根节点的子节点
//遍历节点,打印所有节点名称
public static void listElement() throws Exception{
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document document = builder.parse("src/person.xml");
//使用递归实现
//得到根节点
list1(document);
}
//递归遍历方法 document是node子类
private static void list1(Node node) {
//判断节点
if(node.getNodeType() == Node.ELEMENT_NODE) {
System.out.println(node.getNodeName());
}
//得到一层子节点
NodeList list = node.getChildNodes();
for(int i=0;i<list.getLength();i++){
Node node1 = list.item(i);
//继续得到node1的子节点 递归
list1(node1);
}
}