java操作XML文件
XML文件可以用来作为一种小型数据库存在,但更多时候在项目中都是用来当成配置文件用的,也就避免不了对XML文件的增上改查操作。
在java中,解析XML文件的方式大致分为两种:DOM解析,SAX解析
先来说DOM解析方式:xml解析器一次性把整个xml文档加载进内存,然后在内存中构建一颗Document的对象树,通过Document对象,得到树上的节点对象,通过节点对象访问(操作)到xml文档的内容。
用的较为多的是Dom4j工具(非官方)解析,简单介绍下Dom4j的使用,具体API文档请下载
Dom4j读取xml文件
SAXReader reader = new SAXReader(); //1.创建一个xml解析器对象 Document doc = reader.read(new File("xxx.xml"));//2.读取xml文档,返回Document对象 获取节点: Iterator<Node> doc.nodeIterator(); //获取当前标签节点下的所有子节点 获取标签: Element elem = doc.getRootElement(); //获取xml文档的根标签(一般创建doc对象后回先调用此方法得到根标签) Element e = elem.element("标签名") //指定名称的第一个子标签 Iterator<Element> iterator = elem.elementIterator("标签名");// 指定名称的所有子标签 List<Element> list = elem.elements(); //获取所有子标签 获取属性: String sttrValue = elem.attributeValue("属性名") //获取指定名称的属性值 Attribute attr = Element.attribute("属性名");//获取指定名称的属性对象 attr.getName() //获取属性名称 attr.getValue() //获取属性值 List<Attribute> elem.attributes(); //获取所有属性对象 Iterator<Attribute> elem.attributeIterator(); //获取所有属性对象 获取文本: elem.getText(); //获取当前标签的文本 elem.elementText("标签名") //获取当前标签的指定名称的子标签的文本内容
Dom4j修改xml文件
增加: DocumentHelper.createDocument() 增加文档 addElement("名称") 增加标签 addAttribute("名称",“值”) 增加属性 修改: Attribute.setValue("值") 修改属性值 Element.addAtribute("同名的属性名","值") 修改同名的属性值 Element.setText("内容") 修改文本内容 删除 Element.detach(); 删除标签 Attribute.detach(); 删除属性 写出文件 XMLWriter writer = new XMLWriter(OutputStream, OutputForamt) wirter.write(Document);
简单代码操作步骤:
1 //1、读取文件 2 Document doc = new SAXReader().read(new File("xxx.xml")); 3 4 //2、修改文件 5 6 //3、写出文件 7 FileOutputStream out = new FileOutputStream("f:/xxx.xml");//指定文件输出的位置 8 //指定写出的格式 9 OutputFormat format = OutputFormat.createCompactFormat(); //紧凑的格式.去除空格换行. 10 //OutputFormat format = OutputFormat.createPrettyPrint(); //格式好的格式.有空格和换行. 11 format.setEncoding("utf-8");//2.指定生成的xml文档的编码 12 XMLWriter writer = new XMLWriter(out,format);//创建写出对象 13 writer.write(doc);//写出对象 14 writer.close();//关闭流
值得注意的是Dom4j还支持xPath,这让我们获取标签得到极大的方便。基本就需要记住两个方法,一句代码,便可以获取所有想获取到的元素
导入xPath支持jar包 jaxen-1.1-beta-6.jar,上面给的文档有。
List<Node> selectNodes("xpath表达式"); // 查询多个节点对象 Node selectSingleNode("xpath表达式"); // 查询一个节点对象
例子:假设有如下这段xml,想要获取 二班赵六 的学生的姓名
1 <?xml version="1.0" encoding="UTF-8"?> 2 <root> 3 <class id="001"> 4 <student id="001"> 5 <name>一班--张三</name> 6 <age>20</age> 7 </student> 8 <student id="002"> 9 <name>一班--李四</name> 10 <age>20</age> 11 </student> 12 </class> 13 <class id="002"> 14 <student id="001"> 15 <name>二班--王五</name> 16 <age>20</age> 17 </student> 18 <student id="002"> 19 <name>二班--赵六</name> 20 <age>20</age> 21 </student> 22 </class> 23 </root>
普通方式获取标签与xpath方式获取标签比较
1 public static void main(String[] args) throws Exception { 2 SAXReader reader = new SAXReader(); 3 Document read = reader.read("./src/NewFile.xml"); 4 Element rootElement = read.getRootElement(); 5 6 //普通方式 7 List<Element> elements = rootElement.elements(); 8 for (Element element : elements) { 9 if("002".equals(element.attributeValue("id"))){ 10 List<Element> elem = element.elements(); 11 for (Element e : elem) { 12 if("002".equals(e.attributeValue("id"))){ 13 Element nameElement = e.element("name"); 14 System.out.println("普通方式: "+nameElement.getText()); 15 } 16 } 17 } 18 } 19 //xpath方式 20 Element nameElement = (Element)rootElement.selectSingleNode("/root/class[@id='002']/student[@id='002']/name"); 21 System.out.println("xpath方式: "+nameElement.getText()); 22 }
执行结果:
普通方式: 二班--赵六
xpath方式: 二班--赵六
可见支持xpath对操作xml文档有多么方便
简单介绍xpath的语法,具体请参照:,http://www.w3cschool.cn/index-14.html,附实例文档
/ 绝对路径 表示从xml的根位置开始或子元素(一个层次结构) // 相对路径 表示不分任何层次结构的选择元素。 * 通配符 表示匹配所有元素 [] 条件 表示选择什么条件下的元素 @ 属性 表示选择属性节点 and 关系 表示条件的与关系(等价于&&) text() 文本 表示选择文本内容
SAX解析(官方):
这种解析方式原理是一边加载,一边处理,类似于事件的处理机制,适合xml文件较大的情况
核心API:
SAXParser类: 用于读取和解析xml文件对象 parse(File f, DefaultHandler dh)//解析xml文件 参数一: File,读取的xml文件。参数二: DefaultHandler,SAX事件处理程序。
简单代码实现:详细请查阅api文档
1 public class MyDefaultHandler extends DefaultHandler { 2 3 /** 4 * 开始文档时调用 5 */ 6 @Override 7 public void startDocument() throws SAXException { 8 System.out.println("MyDefaultHandler.startDocument()"); 9 } 10 11 /** 12 * 开始标签时调用 13 * @param qName: 表示开始标签的标签名 14 * @param attributes: 表示开始标签内包含的属性列表 15 */ 16 @Override 17 public void startElement(String uri, String localName, String qName, 18 Attributes attributes) throws SAXException { 19 System.out.println("MyDefaultHandler.startElement()-->"+qName); 20 } 21 22 /** 23 * 结束标签时调用 24 * @param qName: 结束标签的标签名称 25 */ 26 @Override 27 public void endElement(String uri, String localName, String qName) 28 throws SAXException { 29 System.out.println("MyDefaultHandler.endElement()-->"+qName); 30 } 31 32 /** 33 * 读到文本内容的时调用 34 * @param ch: 表示当前读完的所有文本内容 35 * @param start: 表示当前文本内容的开始位置 36 * @param length: 表示当前文本内容的长度 37 */ 38 @Override 39 public void characters(char[] ch, int start, int length) 40 throws SAXException { 41 //得到当前文本内容 42 String content = new String(ch,start,length); 43 System.out.println("MyDefaultHandler.characters()-->"+content); 44 } 45 46 /** 47 * 结束文档时调用 48 */ 49 @Override 50 public void endDocument() throws SAXException { 51 System.out.println("MyDefaultHandler.endDocument()"); 52 } 53 54 } 55 public class Demo1 { 56 public static void main(String[] args) throws Exception{ 57 //1.创建SAXParser对象 58 SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); 59 //2.调用parse方法 60 /** 61 * 参数一: xml文档 62 * 参数二: DefaultHandler的子类 63 */ 64 parser.parse(new File("./src/contact.xml"), new MyDefaultHandler()); 65 } 66 }