前言:xml解析主要分为dom解析和sax解析,dom是W3C组织推荐的处理XML文档的一种方式,sax不是官方标准,但它是xml社区事实上的标准(相当于是一个民间标准),几乎
所有的xml解析器都支持它。dom和sax都是一种模型,都需要使用具体的代码去实现它。dom4j组织根据自己的解析器推出了解析xml的api dom4j,它是一个十分优秀的API,具有
性能优异、功能强大和极易使用的特点,一经推出就风靡。
一、sax解析
1.1sax解析的特点
sax解析xml文件时,遇到开始标签、结束标签、开始解析文件,文件解析结束,字符内容和空白字符时都会触发各自的方法。
优点:适合解析大文件,对内存要求不高。轻量级的解析数据方式,效率更高
缺点:不能随机解析文件,不能修改xml文件,只能进行查询
在基于sax的程序中,有五个最常用的sax事件
startDocument() ---> 解析器发现了文档的开始标签
endDocument() ---> 解析器发现了文档结束标签
startElement() ---> 解析器发现了一个起始标签
character() ---> 解析器发现了标签里面的文本值
endElement() ---> 解析器发现了一个结束标签
利用SAX解析xml文档,涉及两个部分:解析器和时间处理器。例如:
package XMLjiexi; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import com.sun.org.apache.xerces.internal.xni.QName; /* 使用sax解析去解析xml文件,sax解析的机制为遇到开始标签结束标签开始解析文件,遇到文本内容和空白内容都会触发方法, 特点:适合解析大文件,对内存要求不高,轻量级的解析,效率更高 缺点:不能随机修改,只能进行查询,不能随机进行解析,因为是从上到下的解析方式 */ public class Saxparse { private List<student> stus; private student stu; public List<student> read(String filePath) { stus=new ArrayList<>(); try { //第一步,获取sax解析工厂对象 SAXParserFactory factory = SAXParserFactory.newInstance(); //第二步,获得sax解析器对象 SAXParser parser = factory.newSAXParser(); //第三步,利用解析器对象解析xml文件,传的第一个is对象为需要解析的xml文件的路径,第二个对象dh为 //sax解析的关键内容,这个内部类写了很多个方法,解析xml文档的方法,我们只需要去实现五个关键的方法。 parser.parse(filePath,new DefaultHandler() { String cuurentQname; @Override public void characters(char[] ch, int start, int length) throws SAXException { //System.out.println("获取元素内容"); String text=new String(ch, start, length); if("name".equals(this.cuurentQname)) { stu.setName(text); }else if("age".equals(this.cuurentQname)) { stu.setAge(Integer.parseInt(text)); } } @Override public void endDocument() throws SAXException { System.out.println("文档解析结束"); } //当解析到下一个stu时,这个时候已经解析完一个部分了,把这个所有内容保存进list对象stus里面去。 @Override public void endElement(String uri, String localName, String qName) throws SAXException { //System.out.println("元素解析结束"); if(qName.equals("stu")) { stus.add(stu); } this.cuurentQname=null; } @Override public void startDocument() throws SAXException { System.out.println("文档开始解析"); } /*各个参数的含义 * uri:命名空间 * localName:不带前缀名 * qName:带前缀名 * attributes:属性对象 */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { this.cuurentQname=qName; //System.out.println("元素开始解析"); if(qName.equals("stu")) { //当解析到stu时,需要创建一个对象去存储接下来会获取到的属性值 stu=new student(); //属性内容可以通过属性名或者索引来获取属性内容 String id = attributes.getValue("id"); //属性内容的格式是string类型的,需要把它转换为long内容再存进域对象stu里面。ps:开始设置 //stu时的属性为long类型 stu.setId(Long.parseLong(id)); } } } ); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return stus; } public static void main(String[] args) { List<student> stus = new Saxparse().read("src/XMLjiexi/Student.xml"); System.out.println(stus.toString()); } }
二、DOM解析
2.1dom解析的特点
采用dom解析,会将xml文档全部加载到内存当中,然后将xml文档中的所有内容转化为tree上的节点(对象).
优点:可以随机解析,可以修改文件,可以创建xml文件
缺点:适合解析小型文件,对内存要求较高。
三、dom4j解析
3.1dom4j解析简介
dom4j是一个简单、灵活的开放源代码的库。现在很多软件采用的dom4j,使用dom4j开发,需要下载相应的jar包。
3.2dom4j创建、解析、修改xml文件
创建一个和遍历一个xml文档
package XMLjiexi; import java.io.File; import java.io.FileOutputStream; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; /* * 使用dom4japi可以创建和解析和修改xml文件,以下是一些创建和修改相关的操作以及注释 */ public class Dom4jTest { //创建一个新的xml文件 public void createDom(String file){ //获得文档对象 Document document = DocumentHelper.createDocument(); //添加根元素 Element root = document.addElement("root"); //根元素下面添加子元素及其属性 Element city = root.addElement("city"); city.addAttribute("name", "上海"); //city元素下面添加子元素及其文本值 Element num = city.addElement("peopleNumber"); num.addText("23343"); Element sal = city.addElement("salary"); sal.addText("12000"); Element city1 = root.addElement("city"); city1.addAttribute("name", "北京"); //city元素下面添加子元素及其文本值 Element num1 = city1.addElement("peopleNumber"); num1.addText("11111"); Element sal1 = city1.addElement("salary"); sal1.addText("14000"); try { // 输出格式化xml OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter xw = new XMLWriter(new FileOutputStream(new File(file)),format); xw.write(document); xw.flush(); xw.close(); } catch (Exception e) { e.printStackTrace(); } } public void readXML(String filePath){ try { //获得一个SAXReader对象 SAXReader reader = new SAXReader(); File file = new File(filePath); //读取这个要解析的xml文件 Document document = reader.read(file); //获得document中的根节点 Element rootElement = document.getRootElement(); //获得根节点下面所有的子节点 List<Element> elements = rootElement.elements(); //遍历elements集合,拿到每一个子节点 for(Element e:elements){ //获得元素的名字和文本值 String s = e.attributeValue("id"); System.out.println(e.getName()+"节点的id属性的值为:"+s); //获得当前这个子节点下面所有的子节点 List<Element> elements2 = e.elements(); //遍历elements2集合,拿到每一个子节点 for(Element e2:elements2){ System.out.println(e2.getName()+" : "+e2.getText()); } } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Dom4jTest t = new Dom4jTest(); String filePath = "src/XMLjiexi/app.xml"; t.createDom(filePath); // t.readXML(filePath); } }
修改一个xml文件,需要下载相应的jar包
package XMLjiexi; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; public class Dom4jUpdate { public void modifyXML(File filePath) { try { SAXReader reader = new SAXReader(); Document document = reader.read(filePath); //System.out.println("nihao"); //定位节点需要用到一个jar包:jaxen-1.1-beta-6.jar List list = document.selectNodes("//city/@name"); //System.out.println("nihaomingtian"); Iterator iter = list.iterator(); while(iter.hasNext()) { Attribute att = (Attribute)iter.next(); if(att.getValue().equals("上海")) { att.setValue("成都"); } } XMLWriter output=new XMLWriter(new FileWriter(new File("C:/xml/app-modify.xml"))); } catch (DocumentException e) { System.out.println(e.getMessage()); } catch (IOException e) { System.out.println(e.getMessage()); } } public static void main(String[] args) { Dom4jUpdate update = new Dom4jUpdate(); update.modifyXML(new File("C:/Users/YF/eclipse-workspace-javaee/XML/src/XMLjiexi/app.xml")); } }