Java怎么解析XML文档
u 经验(重要)
² 查询的方法一定要用遍历吗?
对XML文档进行读取(查询),不一定要用遍历,如果我们知道XML文档的格式,而且我们题目没有要求我们要读取全部的内容出来,我们就没必要读取全部,. XML文档中Element对象有一个方法是getTextContent() 就是获取内容,如果在根元素(如下面的class)用这个,则读取的是全部内容,即整个XML的内容,如果在还有包含元素的元素(如下面的stu)上用这个,也会读取所包含的所有内容.
|
u 一个简单的入门案例
² XML文档
<?xml version="1.0" encoding = "UTF-8"?> <!-- 这个是可以引用CSS样式表的,但是不常用,通常不会用这个,了解就可以了.这个就是用PI(处理指令)来执行的 <?xml-stylesheet type="text/css" href="my.css"?> --> <class> <stu id ="1130030150" score = "90"> <name>仲夏</name> <sex>男</sex> <age>20</age> <intro><![CDATA[这里可以是一个小图片的字符串,(所有文件都是有二进制组成的,所以小图片也可以看成一个字符串)]]></intro> </stu> <stu id = "1130030151"> <name>柠檬</name> <sex>女</sex> <age>20</age> </stu> </class>
<!--面试题: 问:XML可以传小图片吗? 答:可以,可以把小图片读取成一个byte[]字符串,然后放在CDATA节里面,在传递 --> |
² Java对XML的查询(遍历):
package com.zhongxia;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList;
public class GetXmlInformation { public static void main(String[] args) throws Exception{ //第一步,定义一个XML解析器工厂对象 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); //第二步,获取一个XML解析器 DocumentBuilder dBuilder = dbf.newDocumentBuilder(); //解析指定XML文件 Document document = dBuilder.parse("src/classes.xml"); GetXmlInformation gxi = new GetXmlInformation(); //gxi.List(document); gxi.getNodeValues(document); } //在来获取XML节点里面的内容.(比如,获取第一个学生的名字,年龄..) //这里用Node node也是可以的,应为Document是Node的子类,所以这里用Node你传参数传Document也是可以 public void getNodeValues(Document document) { //因为一个XML里面可能有多个stu,所以用节点集合 NodeList nodeList = document.getElementsByTagName("stu"); //获取第一个stu Element element = (Element) nodeList.item(0); //element也是Node的一个子类,所以可以强转 /* * 为什么要强转为Element呢?? * 因为Node这个类里面有没有可以直接获取属性的函数, * 只有可以获取元素节点的函数, * */ System.out.println(element.getTextContent()); //获取该节点元素的属性 System.out.println(element.getAttribute("id")); } //遍历XML里面的节点 public void List(Node node) { //输出这个节点的名字 //如果没有指定是取元素,则内容也会取出来,节点有分很多种节点类型,我们选择一种元素节点类型的打印出来 if(node.getNodeType() == Node.ELEMENT_NODE){ System.out.println("名字:"+node.getNodeName()); } //获取这个XMl文件里面的节点 NodeList nodeList = node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) { Node n = nodeList.item(i); //这里使用递归来遍历整个XML ,通常遍历的话,都要使用递归,不然无法遍历的时候很麻烦 List(n); } } }
|
这个是解析XML文档的代码,必须先解析才能增删改查
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); //第二步,获取一个XML解析器 DocumentBuilder dBuilder = dbf.newDocumentBuilder(); //解析指定XML文件 Document document = dBuilder.parse("src/classes.xml");
|
解析这个XML文档主要要注意的几点:
1,当执行到dBuilder.Parse(“文档路径”);时 ,系统会把XML文档加载到内容中;
2,此时XML是与树的形式存储在内存中的(每一个元素和内容都是变成一个节点)
² 对XML的增
//添加一个学生(小明) public void add(Document document) throws Exception{ //创建一个新的元素 Element newStu = document.createElement("stu"); //newStu.setTextContent("小明"); //设置元素的属性 newStu.setAttribute("id", "s11302"); //添加学生中的姓名.性别,年龄 Element newStu_name = document.createElement("name"); newStu_name.setTextContent("小明"); Element newStu_sex = document.createElement("sex"); newStu_sex.setTextContent("男"); Element newStu_age = document.createElement("age"); newStu_age.setTextContent("20"); //把学生的姓名,性别,年龄,添加到学生元素里面 newStu.appendChild(newStu_name); newStu.appendChild(newStu_sex); newStu.appendChild(newStu_age); //把学生添加到根节点下面 document.getDocumentElement().appendChild(newStu); //更新XML文档 因为修改的只是在内存中修改,所以需要我们更新到文档中 TransformerFactory tff = TransformerFactory.newInstance(); Transformer tf = tff.newTransformer(); tf.transform(new DOMSource(document), new StreamResult("src/classes.xml")); } |
注意: 所有创建的元素都要在XML文档,也就是Document这个对象的实例下面创建的
还有,添加元素的时候,注意要添加在节点下面.比如要加到根节点下面..要先document.getDocumentElement()然后再.appendChild(newElement);
不然会直接加到和根节点同一层次..违反了XMl的规定(一个XML只有一个根节点)
² 对XML的删除
//删除第一个学生(仲夏)(就是明确第几个学生)和属性 public void del(Document document) throws Exception{ ////获取我们要删除的那个学生节点 //Node node = document.getElementsByTagName("stu").item(0); ////获取它的父节点,然后删除我们要删的那个节点 //node.getParentNode().removeChild(node); //删除元素属性 Element node = (Element) document.getElementsByTagName("stu").item(0); node.removeAttribute("id"); //更新文档 //获取转换工厂 TransformerFactory ttf = TransformerFactory.newInstance(); //获取转换器 Transformer tf = ttf.newTransformer(); //开始转换 tf.transform(new DOMSource(document), new StreamResult("src/classes.xml")); } |
这里删除的要注意,如果不是要求删除指定第几个的元素的信息,我们就要一个一个的遍历过去,然后找到我们要删除的那个然后再进行删除...
这个是我们应该注意的
还有删除的效率明显比添加慢,因为删除要遍历,而添加不用
² 对XML的修改
public void update(Document document) throws Exception{ //获取第一个学生的元素 Element node = (Element) document.getElementsByTagName("stu").item(0); //获取姓名的元素 Element node_name = (Element) node.getElementsByTagName("name").item(0); //重新设置姓名 node_name.setTextContent("小红"); //修改属性 node.setAttribute("score", "80"); //更新XML文档 因为修改的只是在内存中修改,所以需要我们更新到文档中 TransformerFactory tff = TransformerFactory.newInstance(); Transformer tf = tff.newTransformer(); tf.transform(new DOMSource(document), new StreamResult("src/classes.xml")); } |
这个同样要注意的是: 很删除一样,,如果只给出名字.没说第几个就要开始遍历 慢慢的找...不然没办法
u DOM解析XML文档案例2
² XML文档
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <class> <stu score="80"> <name>小红</name> <sex>女</sex> <age>20</age> </stu> <stu id="s11302"> <name>小明</name> <sex>男</sex> <age>20</age> </stu> </class> |
² 读取所有学生信息
// 查看所有学生的成绩(如果知道XML的格式.不用遍历整个XMl,浪费时间还不讨好) //一个student的节点上有这个节点包含起来的所有信息 public void view(Document document) { // 获取学生节点 NodeList nodeList = document.getElementsByTagName("student"); for (int i = 0; i < nodeList.getLength(); i++) { Element element = (Element) nodeList.item(i); System.out.println("学号: "+ element.getAttribute("sid") +"\t" +"姓名:\t"+ getElementFirstValue(element, "name") +"java:\t"+ getElementFirstValue(element, "java") +"oracle:\t"+ getElementFirstValue(element, "oracle") +"vb:\t"+ getElementFirstValue(element, "vb")); } } |
² 读取学生信息的截图
|
这里就单独讲一下怎么读取,其他修改的都没什么难度.
到这里XMl的DOM操作就差不多了...下面如果学习就是学习SAX操作了....