DOM是java 官方提供,无需导入额外包。

DOM解析的流程如下:

  • 创建DocumentBuilderFactory 的对象
  • 创建 DocumentBuilder 对象
  • 通过DocumentBuilder对象的parse方法将要解析的xml文件加载到当前项目中

test.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<students>
	<student id="1"
		name="张三" />
		<student id="2"
		name="李四" />
</students>

代码如下:

//创建DocumentBuilderFactory的对象
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
		//通过DocumentBuilderFactory对象获取DocumentBuilder对象
		DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();
		//DocumentBuilder 对象的parse 方法可以传入String 类型的URI来进行xml的解析,从而返回Document 对象
		Document doc = docBuilder.parse("test.xml");

接下来就可以doc取xml中的内容

代码如下: 这段可以遍历出student子节点

NodeList studentList=doc.getElementsByTagName("student");
	    System.out.println("一共有 "+studentList.getLength()+" 个student 节点");
	    for(int i=0; i<studentList.getLength(); i++) {
	    System.out.print("开始遍历第 "+(i+1)+"个节点 : ");
	    Node student=studentList.item(i);
	    }
	    System.out.print("结束遍历");

如果开发时候并不清楚student子节点的属性,可以将如下代码加入上面的for循环中遍历属性

NamedNodeMap attrs= student.getAttributes();
	    System.out.println(student.getNodeName()+", 节点值为:"+student.getNodeValue()+", 节点属性有 "+attrs.getLength()+"个");
	    //如果对xml文件的节点属性不清楚,可以通过如下方法进行遍历
	    for(int j=0; j<attrs.getLength();j++) {
	    	Node attr=attrs.item(j);
	    	System.out.println("---- 属性名:"+attr.getNodeName()+",属性值:"+attr.getNodeValue());
	    }

如果清楚知道student子节点的属性确定为id 和name,则代码可以简化为 (该代码需写入节点循环中):

Element classpath = (Element)studentList.item(i);
		String id=classpath.getAttribute("id");
		String name=classpath.getAttribute("name");
		System.out.println("---- 属性名:kind ,属性值:"+id);
		System.out.println("---- 属性名:path ,属性值:"+name);

将子节点直接强制转成Element,使用方法getAttribute直接获取属性值。

上面是读取节点的属性名,属性值,接下来简单介绍如何获取节点内子节点的名字和内容

xml 结构如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<students>
	<student id="1">
	   <name>zhangsan</name>
	   <age>20</age>
	</student>
	<student id="2">
	    <name>lisi</name>
	    <age>25</age>
	</student>
</students>

遍历代码如下所示:

NodeList studentList=doc.getElementsByTagName("student");
	  	
	    System.out.println("一共有 "+studentList.getLength()+" 个student 节点");
	    for(int i=0; i<studentList.getLength(); i++) {
	    System.out.print("开始遍历第 "+(i+1)+"个节点 : ");
		Element classpath = (Element)studentList.item(i);
		String id=classpath.getAttribute("id");
		System.out.println("---- 属性名:id ,属性值:"+id);
		//开始遍历student下的子节点的<name> and <age>
		NodeList childNodes=studentList.item(i).getChildNodes();
		for(int k =0; k<childNodes.getLength();k++) {
		Node subNode=childNodes.item(k);
//		Node Type:
//		1	ELEMENT_NODE
//		2	ATTRIBUTE_NODE
//		3	TEXT_NODE
		if(subNode.getNodeType()==Element.ELEMENT_NODE) {
//			System.out.println(subNode.getNodeName()+"=="+subNode.getFirstChild().getNodeValue());
			System.out.println(subNode.getNodeName()+"=="+subNode.getTextContent());
		}

知识点:

1. getChildNodes() 方法获取节点下的所有子节点集合

2. 然后遍历子节点,判断节点类型,节点类型分为元素节点(1),属性节点(2),文本节点(3)。

如果是元素节点,那么getNodeValue()的值都为null,

如<name>zhangsan</name>, name 是元素节点,在dom中,zhangsan

也被看作是name下的子节点(文本节点),可以通过name节点先获取zhangsan节点的对象,然后获取zhangsan节点的值。

即 subNode.getFirstChild().getNodeValue();

而subNode.getTextContent() :这个方法也可以获得zhangsan得值,但是它是获取节点下所有文本节点内容。如

<name><a>sanban</a> zhangsan</name>, 通过上面的方法可以获取的是sanbanzhangsan。