XML解析技术--dom和sax

js使用dom解析标记型文档的方法:根据HTML的层级结构,在内存中分配一个树形结构,把HTML的标签、属性、文本都封装成对象。

对象类型:document对象、element对象、属性对象、文本对象、Node节点对象。

xml解析方式(技术):dom和sax

  • dom:根据xml的层级结构,在内存中分配一个树形结构,把xml中的每部分都封装成对象。
    优点:方便实现增删查改操作。
    缺点:如果文件过大时,造成内存溢出。
  • sax:采用事件驱动,边读边解析。
    从上到下,一行一行解析对象,返回对象名称。
    优点:不存在内存溢出,方便实现查询。
    缺点:不能实现增、删、改操作。

解析xml的解析器

不同的公司和组织提供了针对dom和sax方式的解析器,通过API方式提供:
①sun公司提供了针对dom和sax的解析器 :jaxp
②dom4j组织:dom4j(实际开发中使用较多)
③jdom组织:jdom

jaxp的API查看
jaxp是javase的一部分。
jaxp解析器在jdk的javax.xml.parsers里面。共有四个类,分别是针对dom和sax解析使用的类:

  • dom:
    DocumentBuilder:解析器类
    DocumentBuilderFactory:解析器工厂
  • sax
    SAXParser:解析器类
    SAXParserFactory:解析器工厂

使用dom解析xml

DocumentBuilder是一个抽象类,不能new。可以从DocumentBuilderFactory.newDocumentBuilder()方法获取。
解析xml的方法:Parser " xml(路径) ",返回的是Document整个文档,返回的document是一个接口,父节点是Node。如果在document中找不到想要的方法,可以到父节点Node里去找。

解析步骤:
1.创建解析器工厂
2.根据解析工厂创建解析器
3.解析xml,返回document
4.得到所有的name元素
5.返回集合、遍历集合,得到每一个name元素

在document里面常用的方法:

  • getElementsByTagName(String tagName)
    这个方法可以得到标签,返回NodeList
  • createElement(String tagName) 创建标签
  • createTextNode(String data) 创建文本
  • appendChild(Node newChild) 把文本添加到标签上
  • removeChild(Node oldChild) 删除节点
  • getParentNode() 获取父节点
  • getTextContent() 得到标签里的内容

NodeList list的方法:

  • getLength() 得到集合长度
  • item(int index) 取到下标的具体值

遍历NodeList:

for(int i=0;i<List.getLength();i++){
	List.item(i);
}

使用jaxp实现查询
person.xml文件:

<?xml version="1.0" encoding="UTF-8">
<person>
	<p1>
		<name>张三</name>
		<age>20</age>
	</p1>
	<p1>
		<name>李四</name>
		<age>21</age>
	</p1>
</person>

查询所有name元素的值
Text.java文件:

public class Text {
	public static void main(String [] args ) {
//创建解析器工厂
		DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
		//创建解析器
		DocumentBuilder builder=builderFactory.newDocumentBuilder();
		//得到xml返回document
		Document document=(Document) builder.parse("src/person.xml");
		//得到name元素
		NodeList list=((org.w3c.dom.Document) document).getElementsByTagName("name");
		//遍历集合
		for(int i=0;i<list.getLength();i++){
			Node name1=(Node) list.item(i);  //得到每一个name元素
			String  s=name1.getTextContent();   //得到每一个name元素的值
			System.out.println(s);
		}
	}
}

查询xml中第一个name元素的值
将代码封装成一个方法:selectIn(),在main中调用。
步骤:
1.创建解析器工厂
2.根据解析器工厂创建解析器
3.解析xml,返回document
4.得到所有name元素
5.使用item方法通过下标获取第一个元素
6.得到具体的值,使用getTextContent()

public static void selectIn() 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");
		//使用下标得到第一个元素
		Node name1= list.item(0);
		//得到name的具体值
		String si=name1.getTextContent();
	}

使用jaxp添加节点
在person.xml文件中添加一个节点,在main中调用。

<p1>
		<name>张三</name>
		<age>20</age>
		<sex>男</sex>
</p1>

步骤:
1.创建解析器工厂
2.根据解析器工厂创建解析器
3.解析xml,返回document
4.得到第一个p1,使用item下标获得
5.创建sex标签,createElement
6.创建文本,createTextNode
7.把文本添加到sex下面,appenChild
8.把sex添加到第一个p1下面
9.回写xml,前面的操作都是在xml内存中进行

Text.java文件:

	private static void addSex() throws Exception{
		//创建解析器工厂
		DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
		//根据解析器工厂创建解析器
		DocumentBuilder builder=builderFactory.newDocumentBuilder();
		//解析xml
		Document document=builder.parse("src/person.xml");
		//得到第一个p1标签
		NodeList list=document.getElementsByTagName("p1");  //得到所有p1
		Node p1=list.item(0);
		//创建sex标签
		Element sex1=document.createElement("sex");
		//创建文本
		Element text1=document.createTextNode("男");
		//把文本添加到sex下
		sex1.appendChild(text1);
		//把sex添加到p1
		p1.appendChild(sex1);
		
		//回写xml  Transform(Source xmlSource,Result outputTarget)
		TransformerFactory transformerFactory=TransformerFactory.newInstance();
		Transform transform=transformerFactory.newTransformer();
		transform.transform(new DOMSource(document), new StreamResult("src/person.xml"));	
	}

使用jaxp修改节点
修改第一个p1下面的sex为“女”,使用setTextContent()方法,在main中调用。

Text.java文件:

private static void modifySex() {
		//创建解析器工厂
		DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
		//根据解析器工厂创建解析器
		DocumentBuilder builder=builderFactory.newDocumentBuilder();
		//解析xml
		Document document=(Document) builder.parse("src/person.xml");
		Node sex1=document.getElementsByTagName("sex").item(0);
		//修改sex值
		sex1.setTextContent("女");
		//回写xml
		TransformerFactory transformerFactory=TransformerFactory.newInstance();
		Transform transform=(Transform) transformerFactory.newTransformer();
		transform.transform(new DOMSource((org.w3c.dom.Node) document), new StreamResult("src/person.xml"));
	}

使用jaxp删除节点
删除第一个p1的sex节点,通过获取父节点getParentNode,删除removeChild()子节点。

private static void deleteSex() {
		//创建解析器工厂
		DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
		//根据解析器工厂创建解析器
		DocumentBuilder builder=builderFactory.newDocumentBuilder();
		//解析xml
		Document document=(Document) builder.parse("src/person.xml");
		Node sex1=document.getElementsByTagName("sex").item(0);
		//得到sex的父节点
		Node p1=sex1.getParentElement();
		//删除操作
		p1.removeChild(sex1);
		//回写xml
		TransformerFactory transformerFactory=TransformerFactory.newInstance();
		Transform transform=(Transform) transformerFactory.newTransformer();
		transform.transform(new DOMSource((org.w3c.dom.Node) document), new StreamResult("src/person.xml"));		
	}

使用jaxp遍历节点
遍历节点,把所有元素名称都打印出来。
使用递归算法实现:①得到根节点;②得到根节点的子节点;③得到根节点子节点的子节点…

	private static void List() throws Exception{
		//创建解析器工厂
		DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
		//根据解析器工厂创建解析器
		DocumentBuilder builder=builderFactory.newDocumentBuilder();
		//解析xml
		Document document=(Document) builder.parse("src/person.xml");
		//编写一个方法实现遍历操作
		List1();
		
	}
	
	private static void List1(Node node) {
		//判断元素是否为元素类型时打印,无此判断时空格换行都打印
		if(node.getNodeType()==Node.ELEMENT_NODE){
			System.out.println(node.getNodeName());
		}
		//得到第一层子节点
		NodeList list=node.getChildNodes();
		//遍历list
		for(int i=0;i<list.getLength();i++){
			//得到每一个节点
			Node node1=list.item(0);
			List1(node1);  //递归,自己遍历自己
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值