解析XML文件的几种常见操作方法—DOM/SAX/DOM4j
一直想学点什么东西,有些浮躁,努力使自己静下心来看点东西,哪怕是回顾一下知识。看到了xml解析,目前我还没用到过。但多了解一下,加深点记忆和理解也无害处,权当复习吧。
在此只写下常见的三种XML解析方法,即DOM解析、SAX解析、DOM4J解析。
先上一份xml文件,关于xml文件的格式和创建方法,在此不多说了。
1 <?xml version="1.0" encoding="utf-8"?> 2 <root> 3 <class name="class1"> 4 <student> 5 <name>张三</name> 6 <age>20</age> 7 <sex>男</sex> 8 </student> 9 <student> 10 <name>Andy</name> 11 <age>22</age> 12 <sex>female</sex> 13 </student> 14 </class> 15 <class name="class2"> 16 <student> 17 <name>李四</name> 18 <age>15</age> 19 <sex>男</sex> 20 </student> 21 <student> 22 <name>bigbang</name> 23 <age>21</age> 24 <sex>女</sex> 25 </student> 26 </class> 27 </root>
DOM解析是一种消耗内存的解析方法,它先将整个xml文档装入内存,然后顺序读取,解析也是有些复杂,具体的操作都在注释中,不多说了。
1 import java.io.IOException; 2 import java.util.ArrayList; 3 import java.util.List; 4 5 import javax.xml.parsers.DocumentBuilder; 6 import javax.xml.parsers.DocumentBuilderFactory; 7 import javax.xml.parsers.ParserConfigurationException; 8 9 import org.w3c.dom.Document; 10 import org.w3c.dom.Element; 11 import org.w3c.dom.Node; 12 import org.w3c.dom.NodeList; 13 import org.xml.sax.SAXException; 14 15 import com.entity.Student; 16 17 public class DOMParse { 18 19 private Student student; 20 private List<Student> students; 21 22 public void pasre() { 23 students = new ArrayList<Student>(); 24 try { 25 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 26 DocumentBuilder builder = dbf.newDocumentBuilder(); 27 // 在此没有使用InputStream作为参数,直接引用文件路径。 28 Document doc = builder.parse("src/com/parseDom/test.xml"); 29 // 获取整个document元素 30 Element element = doc.getDocumentElement(); 31 // 获取所有<class>子节点 32 NodeList list = element.getElementsByTagName("class"); // <class> 33 // 遍历class子节点 34 for (int i = 0; i < list.getLength(); i++) { 35 Element el = (Element) list.item(i); 36 // 获取<student>节点 37 NodeList stus = el.getElementsByTagName("student"); // <student> 38 // 遍历student子节点 39 for (int j = 0; j < stus.getLength(); j++) { 40 /** 41 * 获取student下所有子节点 此处有7个节点,分别是#text<name> #text<sex> 42 * #text<age> #text 43 * 对应的xml实际是<student>、<name>、#name、<sex>、#sex 44 * 、<age>、#age这七个子节点 45 * **/ 46 NodeList lis = stus.item(j).getChildNodes(); 47 // 每个student节点输出就是一个Student对象 48 student = new Student(); 49 for (int k = 0; k < lis.getLength(); k++) { 50 // 当元素为节点元素时(非textValue),对比后取值 51 if (lis.item(k).getNodeType() == Node.ELEMENT_NODE) { 52 if ("name".equals(lis.item(k).getNodeName())) { // <name> 53 student.setName(lis.item(k).getFirstChild().getNodeValue()); 54 } 55 if ("sex".equals(lis.item(k).getNodeName())) { // <sex> 56 student.setSex(lis.item(k).getFirstChild().getNodeValue()); 57 } 58 if ("age".equals(lis.item(k).getNodeName())) { // <age> 59 student.setAge(Integer.parseInt(lis.item(k).getFirstChild().getNodeValue())); 60 } 61 } 62 } 63 students.add(student); 64 } 65 } 66 67 } catch (ParserConfigurationException e) { 68 e.printStackTrace(); 69 } catch (SAXException e) { 70 e.printStackTrace(); 71 } catch (IOException e) { 72 e.printStackTrace(); 73 } finally { 74 for (Student stus : students) { 75 System.out.println(stus.getName() + "--" + stus.getSex() + "--" + stus.getAge()); 76 } 77 } 78 } 79 80 public static void main(String[] args) { 81 DOMParse domParse = new DOMParse(); 82 domParse.pasre(); 83 } 84 }
SAX解析方法如下,依然看注释说明。
1 import java.io.IOException; 2 import java.util.ArrayList; 3 import java.util.List; 4 5 import javax.xml.parsers.ParserConfigurationException; 6 import javax.xml.parsers.SAXParser; 7 import javax.xml.parsers.SAXParserFactory; 8 9 import org.xml.sax.Attributes; 10 import org.xml.sax.SAXException; 11 import org.xml.sax.helpers.DefaultHandler; 12 13 import com.entity.Student; 14 15 public class SAXParse extends DefaultHandler{ 16 17 18 private Student student; 19 private static List<Student> stus; 20 private String preTag=null; 21 22 //①程序启动执行 23 @Override 24 public void startDocument() throws SAXException { 25 stus = new ArrayList<Student>(); 26 } 27 28 //② 开始遍历元素时 29 @Override 30 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 31 if("student".equals(qName)){ 32 student = new Student(); 33 // student.setName(attributes.getValue(0)); 34 } 35 preTag = qName; 36 } 37 38 //④元素遍历结束 39 @Override 40 public void endElement(String uri, String localName, String qName) throws SAXException { 41 if("student".equals(qName)){ 42 stus.add(student); 43 student = null; 44 } 45 preTag=null; 46 } 47 48 //③ 遍历取值过程 49 @Override 50 public void characters(char[] ch, int start, int length) throws SAXException { 51 if(preTag!=null){ 52 String content = new String(ch,start,length); 53 if("name".equals(preTag)){ 54 student.setName(content); 55 } 56 if("age".equals(preTag)){ 57 student.setAge(Integer.parseInt(content)); 58 } 59 if("sex".equals(preTag)){ 60 student.setSex(content); 61 } 62 } 63 } 64 65 public void fun(){ 66 try { 67 SAXParserFactory factory =SAXParserFactory.newInstance(); 68 SAXParser parser = factory.newSAXParser(); 69 SAXParse handler = new SAXParse(); 70 parser.parse("src/com/parseDom/test.xml", handler); 71 } catch (ParserConfigurationException e) { 72 e.printStackTrace(); 73 } catch (SAXException e) { 74 e.printStackTrace(); 75 } catch (IOException e) { 76 e.printStackTrace(); 77 } 78 } 79 80 public static List<Student> getStus(){ 81 return stus; 82 } 83 84 public static void main(String[] args) { 85 new SAXParse().fun(); 86 for (Student stu : getStus()) { 87 System.out.println(stu.getName()+"--"+stu.getAge()+"--"+stu.getSex()); 88 } 89 } 90 }
DOM4J的解析方法如下,需要注意的是它的Document类和Element类是DOM4J的jar包提供的,不要引用错了。
1 import java.util.ArrayList; 2 import java.util.Iterator; 3 import java.util.List; 4 5 import org.dom4j.Document; 6 import org.dom4j.DocumentException; 7 import org.dom4j.Element; 8 import org.dom4j.io.SAXReader; 9 10 import com.entity.Student; 11 12 public class DOM4J { 13 14 private Student student; 15 private List<Student> stus; 16 17 @SuppressWarnings("unchecked") 18 public void parse(){ 19 stus = new ArrayList<Student>(); 20 try { 21 SAXReader reader = new SAXReader(); 22 23 //此处Document类和Element类均为DOM4j的jar包中的类 24 Document doc = reader.read("src/com/parseDom/test.xml"); 25 //获取根元素 26 Element root = doc.getRootElement(); 27 //获取节点元素为"class"的迭代 28 Iterator<Element> classss = root.elementIterator("class"); 29 while(classss.hasNext()){ 30 Element classs =classss.next(); 31 //获取节点元素为"student"的迭代 32 Iterator<Element> students = classs.elementIterator("student"); 33 while (students.hasNext()) { 34 //每一个student节点元素都包括一个student对象 35 student = new Student(); 36 Element els = students.next(); 37 //根据节点元素取值 38 student.setName(els.elementText("name")); 39 student.setAge(Integer.parseInt(els.elementText("age"))); 40 student.setSex(els.elementText("sex")); 41 stus.add(student); 42 } 43 } 44 } catch (DocumentException e) { 45 e.printStackTrace(); 46 } finally{ 47 for (Student stu : stus) { 48 System.out.println(stu.getName()+"++"+stu.getSex()+"++"+stu.getAge()); 49 } 50 } 51 } 52 53 54 public static void main(String[] args) { 55 new DOM4J().parse(); 56 } 57 }
最后的输出结果是:
1 张三++男++20 2 Andy++female++22 3 李四++男++15 4 bigbang++女++21
其实每个解析的方法差不多,代码量比较小,很好理解。每个方法都有自己的特点,具体使用要看使用的环境了。