一次性把xml文档加载成Document树,通过Document对象得到节点对象,通过节点对象访问xml文档内容(标签,属性,文本,注释)。
以book.xml为例讲解。
<书架>
<书>
<书名>计算机网络书名>
<作者>张三作者>
<售价>100售价>
书>
<书>
<书名>数据结构书名>
<作者>李四作者>
<售价>80售价>
书>
书架>
获得JAXP中的DOM解析器
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
// 加载XML文档
Document document = db.parse("src/book.xml");
1、得到某个具体的节点内容 : eg: 拿到计算机网络的售价
public static void test1(Document document) {
// 拿到所有售价节点
NodeList nl = document.getElementsByTagName("售价");
// 获得计算机网络的售价节点
Node n = nl.item(1);
// 获取售价文本
System.out.println(n.getTextContent());
}
2、遍历所有元素节点
public static void test2(Node node) {
// 对node节点进行循环
NodeList nl = node.getChildNodes();
// 循环判断
for (int i = 0; i < nl.getLength(); i++) {
Node n = nl.item(i);
if (n.getNodeType() == Node.ELEMENT_NODE) {
// 说明此节点就是标签节点
System.out.println(n.getNodeName());
test2(n);
}
}
}
3、修改某个元素节点的主体内容 eg: 修改计算机网络的售价为80
public static void test3(Document document) throws Exception {
// 拿到所有售价节点
NodeList nl = document.getElementsByTagName("售价");
// 获得计算机网络的售价节点
Node n = nl.item(1);
// 修改主体内容
n.setTextContent("80");
// 将修改的结果保存到硬盘上
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));
}
4、向指定元素节点中增加子元素节点:eg:给数据结构的售价增加一个内部价节点 :50
public static void test4(Document document) throws Exception {
// 拿到所有售价节点
NodeList nl = document.getElementsByTagName("售价");
// 获得数据结构的售价节点
Node n = nl.item(0);
// 创建新的节点
Element el = document.createElement("内部价");
// 设置节点的主体内容
el.setTextContent("50");
// 将内部价节点挂接到售价几点上
n.appendChild(el);
// 将修改的结果保存到硬盘上
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));
}
5、向指定元素节点上增加同级元素节点 : eg:给数据结构的售价增加一个批发价节点 :60
public static void test5(Document document) throws Exception {
// 拿到所有书节点
NodeList nl = document.getElementsByTagName("书");
// 获得数据结构的书节点
Node n = nl.item(0);
// 创建批发价节点
Element el = document.createElement("批发价");
// 设置节点的主体内容
el.setTextContent("60");
// 将内部价节点挂接到书点上
n.appendChild(el);
// 将修改的结果保存到硬盘上
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));
}
6、删除指定元素节点 eg: 删除内部价节点
public static void test6(Document document) throws Exception {
// 拿到所有内部价节点
NodeList nl = document.getElementsByTagName("内部价");
// 拿到数据结构的内部价节点
Node node = nl.item(0);
// 父亲干掉儿子
node.getParentNode().removeChild(node);
// 将修改的结果保存到硬盘上
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));
}
7、操作XML文件属性: eg: 给数据结构的书几点增加一个属性: ISBN : "小小程序员"
public static void test7(Document document) throws Exception {
// 拿到所有书节点
NodeList nl = document.getElementsByTagName("书");
// 获得数据结构的书节点
Node n = nl.item(0);
// 增加一个属性
((Element) n).setAttribute("ISBN", "小小程序员");
// 将修改的结果保存到硬盘上
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.transform(new DOMSource(document), new StreamResult("src/book.xml"));
}
i.第一步:读取XML文档信息,生成document对象
1.读取XML文件,获得document对象
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
2.解析XML形式的文本,得到document对象.
String text = " ";
Documentdocument = DocumentHelper.parseText(text);
3.主动创建document对象.
Document document = DocumentHelper.createDocument();
//创建根节点
Element root = document.addElement("members");
ii. 第二步:修改XML文档的信息
1. 增:文档、标签、属性
//1.创建文档
Document doc = DocumentHelper.createDocument();
//2.增加标签
Element rootElem = doc.addElement("contactList");
//doc.addElement("contactList");
Element contactElem = rootElem.addElement("contact");
contactElem.addElement("name");
//3.增加属性
contactElem.addAttribute("id", "001");
contactElem.addAttribute("name", "eric");
2.删:标签、属性
1.删除标签 1.1得到标签对象 1.2删除标签对象
Element ageElem = doc.getRootElement().element("contact").element("age");
//1.2 删除标签对象
ageElem.detach();
//先取得父标签,然后通过父标签移出自己
//ageElem.getParent().remove(ageElem);
2.删除属性 2.1得到属性对象 2.2删除属性
//2.1得到属性对象
//得到第二个contact标签
Element contactElem = (Element)doc.getRootElement().elements().get(1);
//2.2 得到属性对象
Attribute idAttr = contactElem.attribute("id");
//2.3 删除属性
idAttr.detach();
//idAttr.getParent().remove(idAttr);
3. 改:属性值、文本
方案一: 修改属性值 1. 得到标签对象 2. 得到属性对象 3. 修改属性值//1.1 得到标签对象
Element contactElem = doc.getRootElement().element("contact");
//1.2 得到属性对象
Attribute idAttr = contactElem.attribute("id");
//1.3 修改属性值
idAttr.setValue("003");
方案二:修改属性值1.1 得到标签对象1.2 通过增加同名属性的方法,修改属性值
//1.1 得到标签对象
Element contactElem = doc.getRootElement().element("contact");
//1.2 通过增加同名属性的方法,修改属性值
contactElem.addAttribute("id", "004");
修改文本 1.得到标签对象 2.修改文本
Element nameElem = doc.getRootElement().element("contact").element("name");
nameElem.setText("李四");
ii.第三步:将修改后的XML文档写入到文件
FileOutputStream out = new FileOutputStream("e:/contact.xml");
//1.指定写出的格式
//紧凑的格式.去除空格换行.项目上线的时候
OutputFormat format = OutputFormat.createCompactFormat();
//漂亮的格式.有空格和换行.开发调试的时候
//OutputFormat format = OutputFormat.createPrettyPrint();
/**
* 2.指定生成的xml文档的编码
1)导入xPath支持jar包。 jaxen-1.1-beta-6.jar
2)使用xpath方法
List
Node selectSingleNode("xpath表达式"); 查询一个节点对象
3)xPath语法:
/ 绝对路径 表示从xml的根位置开始或子元素(一个层次结构)
// 相对路径 表示不分任何层次结构的选择元素。
* 通配符 表示匹配所有元素
[] 条件 表示选择什么条件下的元素
@ 属性 表示选择属性节点
and 关系 表示条件的与关系(等价于&&)
text() 文本 表示选择文本内容
//创建sax解析器
SAXParser sax =SAXParserFactory.newInstance().newSAXParser() ;
//获取内容读取器
XMLReader xml = sax.getXMLReader() ;
//注册一个内容处理器
xml.setContentHandler(newDefaultHandler(){
String curName ="" ; //记录当前是那个标签
int index = 0 ; //记录读取到了那个作者
public voidstartElement(String uri, String localName,
StringqName, Attributes attributes) throws SAXException {
if(qName.equals("作者")){
curName= "作者" ;
index++ ;
}
}
public voidendElement(String uri, String localName, String qName)
throwsSAXException {
curName ="" ;
}
public voidcharacters(char[] ch, int start, int length)
throwsSAXException {
if("作者".equals(curName)&& index == 2){
//说明读取到了第二本书的作者
System.out.println(newString(ch,start,length));
}
}
}) ;
//加载xml文档
xml.parse("src/book.xml");
============DOM解析 vs SAX解析 ========
DOM解析 |
SAX解析 |
原理: 一次性加载xml文档,不适合大容量的文件读取 |
原理: 加载一点,读取一点,处理一点。适合大容量文件的读取 |
DOM解析可以任意进行增删改成 |
SAX解析只能读取 |
DOM解析任意读取任何位置的数据,甚至往回读 |
SAX解析只能从上往下,按顺序读取,不能往回读 |
DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单。 |
SAX解析基于事件的编程方法。java开发编码相对复杂。 |