欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用jaxp解析器dom方式对xml节点进行操作

程序员文章站 2022-05-28 14:48:16
...

    作为一名初学者,对一些编程语言感觉不是很简单。尤其是正在学习的Javaweb这一部分的内容,非常驳杂,让人头大。

    看过一些书,也包括听一些人说,写博客有利于理解和记忆。作为一名初学者,我抱着学习和积累的心理,开始我的博客之旅。希望各位前辈和同济多指教。

    jaxp,刚开始学习的时候不理解是什么意思,特地百度一下,原来是处理xml的Java api。今天主要学习了xml的dom解析方式。对于jaxp,我也不知道准确的称呼方式,在下文皆称为解析器。jaxp解析器位于jdk api 的javax.xml.parsers包中。其中DocumentBuilder和DocumentBuilderFactory这两个类是针对dom方式的。这两个类都是抽象类,不能通过构造方法实例化,下面是这两个类获取实例的方法:

//创建解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
//通解析器工厂来创建解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();

下面使用jaxp解析器来解析xml文档,给出一个xml文件如下(在下文中此xml文件的位置为src/person.xml):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<perosn>
	<p1>
		<name>zhaosi</name>
		<age>12</age>
	</p1>
	<p1>
		<name>lisan</name>
		<age>22</age>
	</p1>
</perosn>

1.使用jaxp实现查询操作,比如查询所有name元素的值

java代码如下:

public static void selectNames() throws Exception {
		//创建解析器工厂
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
		//创建解析器
		DocumentBuilder builder = builderFactory.newDocumentBuilder();
		//解析xml文件得到Document对象
		Document document = builder.parse("src/person.xml");
		//通过标签(元素)名得到对应的集合
		NodeList names = document.getElementsByTagName("name");
		//遍历集合,并打印节点文本内容
		for (int x=0; x<names.getLength(); x++) {
			Node name = names.item(x);//通过item方法得到集合中第x个项
			System.out.println(name.getTextContent());//获取文本内容并打印
		}
	}

        使用getElementsByTagName()方法可以获得对应元素的集合。如果想要查询某一个元素的值,便不需要遍历,直接使用item()方法即可:

Node name1 = document.getElementsByTagName("name").item(0);

这样便可以得到对应的节点了。


2.使用jaxp实现添加操作,比如在第一个p1标签中age标签的后面添加一个节点<sex>man</sex>

java 代码如下:

public static void addSex() throws Exception {
	//创建解析器工厂
	DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
	//创建解析器
	DocumentBuilder builder = builderFactory.newDocumentBuilder();
	//解析xml文档得到Document对象
	Document document = builder.parse("src/person.xml");
	//得到第一个p1节点
	Node p1 = document.getElementsByTagName("p1").item(0);
	//添加sex节点
	//首先创建sex标签及其文本并结合
	Node sex = document.createElement("sex");
	Text text = document.createTextNode("man");
	sex.appendChild(text);
	//将此节点添加到p1下
	p1.appendChild(sex);
	//回写xml,将源树转换为结果树
	TransformerFactory transformerFactory = TransformerFactory.newInstance();
	Transformer transformer = transformerFactory.newTransformer();
	//转换
	transformer.transform(new DOMSource(document), new StreamResult("src/person.xml"));
}

       可以看到在使用jaxp对xml文件进行操作时,前三步基本上是相同的。而添加节点后之所以需要回写,是因为添加节点的操作改变的是内存中DOM树(源树)的结构,而非xml文件。DOMSource(Source的子类)以DOM树的形式充当源树的持有者,StreamResult(Result的子类)充当转换结果的持有者。


3.使用jaxp实现修改操作,比如将sex标签的内容改为woman

public static void setSex() throws Exception {
	//创建解析器工厂
	DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
	//根据解析器工厂创建解析器
	DocumentBuilder builder = builderFactory.newDocumentBuilder();
	//解析xml文件,得到Document对象
	Document document = builder.parse("src/person.xml");
	//得到sex节点
	Node sex = document.getElementsByTagName("sex").item(0);
	//修改节点文本内容
	sex.setTextContent("woman");
	//回写
	TransformerFactory transformerFactory = TransformerFactory.newInstance();
	Transformer transformer = transformerFactory.newTransformer();
	transformer.transform(new DOMSource(document), new StreamResult("src/person.xml"));
}

4.使用jaxp实现删除操作,比如删除sex节点

public static void removeSex() throws Exception {
	//创建解析器工厂
	DocumentBuilderFactory builderFactory  = DocumentBuilderFactory.newInstance();
	//通过解析器工厂得到解析器
	DocumentBuilder builder = builderFactory.newDocumentBuilder();
	//解析xml文件得到Document对象
	Document document = builder.parse("src/person.xml");
	//得到sex节点
	Node sex = document.getElementsByTagName("sex").item(0);
	//得到sex节点的父节点
	Node sexParent = sex.getParentNode();
	//删除
	sexParent.removeChild(sex);
	//回写
	TransformerFactory transformerFactory = TransformerFactory.newInstance();
	Transformer transformer = transformerFactory.newTransformer();
	transformer.transform(new DOMSource(document), new StreamResult("src/person.xml"));
}


5.使用jaxp遍历所有节点

public static void nodesTraversal() throws Exception {
	//创建解析器工厂
	DocumentBuilderFactory builderFactory  = DocumentBuilderFactory.newInstance();
	//通过解析器工厂得到解析器
	DocumentBuilder builder = builderFactory.newDocumentBuilder();
	//解析xml文件得到Document对象
	Document document = builder.parse("src/person.xml");
	//遍历
	recurMethod(document);
}
//使用递归的方式进行节点的遍历
public static void recurMethod(Node node) {
	if(node.getNodeType()==Node.ELEMENT_NODE) {
		//先判断其是否为元素节点,是则打印
		System.out.println(node.getNodeName());
	}
	if(node.hasChildNodes()) {//判断其是否存在子节点
		//如果该节点存在子节点则进行其子节点的遍历
		NodeList nodeList = node.getChildNodes();
		for (int x=0; x<nodeList.getLength(); x++) {
			Node childNode = nodeList.item(x);
			recurMethod(childNode);//递归
		}
	}
}
        以上内容,作为对初学jaxp解析器dom方式解析xml的输出和加强。如果有什么错误或者误差亦或是缺失,希望得到指正哈!