一个xml文件如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <books> 3 <book> 4 book text 5 </book> 6 </books>
dom解析如下:
1 public class parseTest 2 { 3 public static void main(String[] args) throws Exception 4 { 5 //创建工厂类。 6 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 7 //用工厂类创建一个文档(document)解析器。 8 DocumentBuilder builder = factory.newDocumentBuilder(); 9 //builder.parse()将给定的内容解析为一个XML文档,并且返回一个新的DOM 对象。 10 Document document = builder.parse(new File("test.xml")); 11 //获取文档的根节点。 12 Element root = document.getDocumentElement(); 13 //获取root根节点的所有的子节点。 14 NodeList booksNodes = root.getChildNodes(); 15 16 System.out.println("--------------华丽的分割线--node--------------"); 17 for(int i=0;i<booksNodes.getLength();i++){ 18 System.out.println(booksNodes.item(i)); 19 } 20 System.out.println("--------------华丽的分割线--node.getNodeValue()--------------"); 21 for(int i=0;i<booksNodes.getLength();i++){ 22 System.out.println(booksNodes.item(i).getNodeValue()); 23 } 24 System.out.println("--------------华丽的分割线--node.getFirstChild()--------------"); 25 for(int i=0;i<booksNodes.getLength();i++){ 26 System.out.println(booksNodes.item(i).getFirstChild()); 27 } 28 System.out.println("--------------------------------------------------------"); 29 System.out.println("根节点下的节点总数:"+booksNodes.getLength()); 30 } 31 }
结果如下图:
为什么呢?
1 <?xml version="1.0" encoding="UTF-8"?> 2 <books> 3 before 4 <book> 5 book text 6 </book> 7 after 8 </books>
运行之后,结果如下图:
ok,结果说明一切。下面开始总结:
首先,我们要先了解xml文件的节点的种类,一种是ElementNode,一种是TextNode。然后... ...
1. 每个子节点与父节点之间都有默认的Text节点,如果没有赋值的话,节点内容为空,但仍然作为一个空节点存在着。
2. DOM把<book>book text</book>也当作是两层结构的节点,其父节点为<book>节点本身,子节点是一个Text节点。因此,
node.getNodeValue()获得是<book>节点的value值,而node.getFirstChild().getNodeValue()获得的才是Text节点的Value值。
下面是SAX解析XML
SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。其解析是按照xml文件的顺序一步一步一行一行的来解析。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <persons> 3 <person id="23"> 4 <name>李明</name> 5 <age>30</age> 6 </person> 7 <person id="20"> 8 <name>李向梅</name> 9 <age>25</age> 10 </person> 11 </persons>
1 public class ParseSax 2 { 3 public static void main(String[] args) 4 { 5 try 6 { 7 FileInputStream input = new FileInputStream(new File("person.xml")); 8 List<HashMap<String,String>> list = parseSax(input,"person"); 9 for(HashMap<String,String> book : list){ 10 System.out.println(book.toString()); 11 } 12 } 13 catch (Exception e) 14 { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 } 18 } 19 20 public static List<HashMap<String,String>> parseSax(InputStream input,String nodeName) throws ParserConfigurationException, SAXException, IOException{ 21 //创建SAX工厂 22 SAXParserFactory factory = SAXParserFactory.newInstance(); 23 //创建SAX解析器 24 SAXParser parser = factory.newSAXParser(); 25 SaxHandler handler = new SaxHandler(nodeName); 26 parser.parse(input,handler); 27 input.close(); 28 return handler.getList(); 29 30 } 31 }
1 public static class SaxHandler extends DefaultHandler{ 2 private HashMap<String,String> map = null; 3 private List<HashMap<String,String>> list = null; 4 private String currentTag = null;//正在解析的元素的标签 5 private String currentValue = null;//正在解析的元素的值 6 private String nodeName = null; 7 8 public List<HashMap<String,String>> getList(){ 9 return list; 10 } 11 public SaxHandler(String nodeName){ 12 this.nodeName = nodeName; 13 } 14 15 @Override 16 //当读取<?xml...>时,会调用startDocument()方法 17 public void startDocument() throws SAXException 18 { 19 list = new ArrayList<HashMap<String,String>>(); 20 } 21 22 @Override 23 //当读取一个ElementNode的时候,会调用此方法。qName是节点名称,attributes是这个节点的属性。 24 public void startElement(String uri, String localName, String qName, 25 Attributes attributes) throws SAXException 26 { 27 if(qName.equals(nodeName)){ 28 map = new HashMap<String, String>(); 29 } 30 if(attributes !=null && map !=null){ 31 for(int i=0;i<attributes.getLength();i++){ 32 map.put(attributes.getQName(i),attributes.getValue(i)); 33 } 34 } 35 currentTag = qName; 36 } 37 38 @Override 39 public void endElement(String uri, String localName, String qName) 40 throws SAXException 41 { 42 if(qName.equals(nodeName)){ 43 list.add(map); 44 map = null; 45 } 46 super.endElement(uri, localName, qName); 47 } 48 49 @Override 50 //当遇到TextNode节点时,调用此方法 51 public void characters(char[] ch, int start, int length) 52 throws SAXException 53 { 54 if(currentTag !=null && map !=null){ 55 currentValue = new String(ch,start,length); 56 if(currentValue !=null && !currentValue.equals("")&&!currentValue.replaceAll("\\s"," ").trim().equals("")){ 57 map.put(currentTag, currentValue); 58 } 59 } 60 currentTag = null; 61 currentValue = null; 62 } 63 }
DOM4J解析
1 SAXReader reader = new SAXReader(); 2 Document doc = reader.read(new File("person.xml")); 3 4 Element rootElt = doc.getRootElement();//获得根节点 5 System.out.println("根节点:"+rootElt.getName()); 6 7 Iterator<?> iter = rootElt.elementIterator();//遍历根节点下子节点 8 while(iter.hasNext()){ 9 Element element = (Element) iter.next(); 10 Attribute attr = element.attribute(0); 11 System.out.println(attr.getName()+"="+attr.getValue()); 12 Iterator<?> iters = element.elementIterator(); 13 while(iters.hasNext()){ 14 Element ele = (Element) iters.next(); 15 System.out.println(ele.getText()); 16 } 17 }
根节点:persons
id=23
李明
30
id=20
李向梅
25