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。