xml文件:树形存储格式;通过相同的xml文件实现不同的软件、不同的操作系统、不同的平台之间的信息通讯;
声明xml文件:
<?xml version="1.0" encoding="utf-8"?>
本篇用来测试的xml文件:
<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book id = "1"> <name>童话故事</name> <author>安徒生</author> </book> <book id = "2"> <name>大力水手</name> <year>1999</year> </book> </bookstore>
注意:
xml文件中的空格换行符会被java解析成Text类节点;
java获取xml文件内容的解析方式有;DOM、SAX、DOM4J、JDOM
DOM解析:
两种取节点值的区别:
getNodevalue():取普通的节点值会返回一个null,因为Java是把我们以为的节点值看成是一个子节点的,因此需要getFirstChild().getNodeValue()这样来取得我们认为的节点值;
getTextContent():是把节点的节点值和子节点的节点值都当做是节点值取出并返回,比如节点<book><id>88<id>童话故事</book>;这样取出来的值是88童话故事;
SAX解析xml文件:没有将xml文件全部加载到内存中,而是通过识别文件开始、结束标志,节点的开始、结束标志;遍历整个xml文件
继承DefaultHandler,并重写一些方法,在业务中实例化这个类并作为参数将其传入;
继承DefaultHandler的重写方法类:
package com.hd; import java.util.ArrayList; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import com.entry.Book; public class SAXHd extends DefaultHandler { int books = 0; String nodevalue = null; Book ii = null; private ArrayList<Book> bookList = new ArrayList<Book>(); public ArrayList<Book> getBookList() { return bookList; } @Override public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub super.characters(ch, start, length); nodevalue = new String(ch, start, length); if(!nodevalue.trim().equals("")) { System.out.println("对应的节点值是:"+nodevalue); } } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // TODO Auto-generated method stub super.startElement(uri, localName, qName, attributes); if(qName.equals("book")) { ii = new Book(); int i = attributes.getLength(); for(int j =0;j<i;j++) { String atrname = attributes.getQName(j); String atrvalue = attributes.getValue(j); System.out.println("book节点的属性有"+i+"个,第"+(j+1)+"个属性名是:"+atrname+",其对应的属性值是:"+atrvalue); if(attributes.getQName(j).equals("id")) { ii.setId(atrvalue); } } }else if (!qName.equals("book") && !qName.equals("bookstore")){ System.out.println("节点名是:"+qName); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub super.endElement(uri, localName, qName); if(qName.equals("book")) { bookList.add(ii); ii = null; books++; System.out.println("===========结束第"+books+"本书的遍历==========="); }else if (qName.equals("name")) { ii.setName(nodevalue); }else if (qName.equals("author")) { ii.setAuthor(nodevalue);; }else if (qName.equals("year")) { ii.setYear(nodevalue); } } @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub super.startDocument(); System.out.println("开始解析"); } @Override public void endDocument() throws SAXException { // TODO Auto-generated method stub super.endDocument(); System.out.println("解析结束"); } }
book对象的封装类:
package com.entry; public class Book { private String id; private String name; private String year; private String author; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getYear() { return year; } public void setYear(String year) { this.year = year; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } }
解析过程的执行结果类:
package com.xmltest; import java.io.IOException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; import com.entry.Book; import com.hd.SAXHd; public class SAXTest { public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { // TODO Auto-generated method stub SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); SAXHd hd = new SAXHd(); parser.parse("books.xml", hd); System.out.println(hd.getBookList().size()); for (Book book : hd.getBookList() ) { System.out.println(book.getId()); System.out.println(book.getAuthor()); System.out.println(book.getName()); System.out.println(book.getYear()); System.out.println("--------------------"); } } }
以上的两种xml文件的解析方法是java本身提供的;
而DOM4J、JDOM方法解析xml文件是需要导入对应的java包,比较稳妥的做法是在项目先建一个folder文件后将jar包拉进去,再通过build path中加入进去,而不是仅仅选择build path加载进去,这样可以避免因项目跨平台的传送而导致在别的电脑上运行时没有加载jar包;
jdom解析xml文件
若发现解析出来的xml文件出现乱码,先检查xml文件声明时的字符编码;如若无果,再去将xml文件读入输入流的时候设置好字符编码;
package com.JdomTest; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.jdom2.Attribute; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import com.entry.Book; public class JDOMtest01 { private static ArrayList<Book> booklist = new ArrayList<Book>(); public static void main(String[] args) throws JDOMException, IOException { // TODO Auto-generated method stub SAXBuilder saxBuilder = new SAXBuilder();//创建一个SAXBuilder对象 InputStream in = new FileInputStream("books.xml");//创建一个输入流; Document document = saxBuilder.build(in);//将输入流加载到saxBuilder.build()中; Element rootElement = document.getRootElement();//获取根节点 List<Element> bookList = rootElement.getChildren();//获取根节点下的子节点集合 for(Element y : bookList) { Book book = new Book(); System.out.println("========开始解析第"+(bookList.indexOf(y)+1)+"书========"); List<Attribute> attr = y.getAttributes();//获取y子节点的属性集合 for(Attribute x : attr) { String atrname = x.getName(); String atrvalue = x.getValue(); System.out.println("属性名:"+atrname+";属性值:"+atrvalue); if (atrname.equals("id")) { book.setId(atrvalue); } } List<Element> node = y.getChildren(); for (Element z : node) { String nodename = z.getName(); String nodevalue = z.getValue(); System.out.println("子节点名:"+nodename+",对应的值是"+nodevalue); if (nodename.equals("name")) { book.setName(nodevalue); } else if (nodename.equals("author")) { book.setAuthor(nodevalue); } else if (nodename.equals("year")) { book.setYear(nodevalue); } } booklist.add(book); book = null; System.out.println("========结束解析第"+(bookList.indexOf(y)+1)+"书========"); } System.out.println(booklist.get(0).getId()); System.out.println(booklist.get(0).getAuthor()); System.out.println(booklist.get(0).getName()); System.out.println(booklist.get(0).getYear()); } }
dom4j解析xml文件
package com.dom4jtest; import java.io.File; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class Dom4jTest01 { public static void main(String[] args) throws DocumentException { // TODO Auto-generated method stub SAXReader reader = new SAXReader();//创建SAXReader对象; Document document = reader.read(new File("books.xml"));//将xml文件传入Document对象中 Element bookstore = document.getRootElement();//获取根节点 Iterator it = bookstore.elementIterator();//获取包含子节点的迭代器; while(it.hasNext()) { System.out.println("=======开始遍历某本书======="); Element book = (Element)it.next();//对迭代器中的对象进行强制转换; Iterator node = book.elementIterator(); while(node.hasNext()) { Element booknode = (Element)node.next(); String nodename = booknode.getName(); String nodevalue = booknode.getStringValue(); System.out.println("子节点名:"+nodename+",对应的子节点值:"+nodevalue); } List<Attribute> bookatrs = book.attributes();//获取book的属性集 for(Attribute i : bookatrs) { String strname = i.getName(); String strvalue = i.getValue(); System.out.println("这本书的属性名是:"+strname+",其对应的属性值是:"+strvalue); } System.out.println("=======结束遍历某本书======="); } } }
同样的,也可通过对自定义对象的封装实例化,将取得的值存进对象中并保存起来;
四种解析xml文件的对比: