(十一)补充读取xml文件的四种方式代码
一、为什么使用XML
1、便于不同应用程序之间通信。
2、便于不同平台之间通信。
3、便于不同平台之间数据共享。
二、Dom读取
xml文件内容
<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book id="1"> <name>冰与火之歌</name> <author>乔治马丁</author> <year>2014</year> <price>89</price> </book> <book id="2"> <name>安徒生童话</name> <year>2004</year> <price>77</price> <language>English</language> </book> </bookstore>
dom代码
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.dom4j.Node; import org.w3c.dom.Document; import org.w3c.dom.NodeList; public class DomReadXml { public static void main(String[] args) { readXml(); } public static void readXml() { try { // 创建解析器工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder db = factory.newDocumentBuilder(); // 创建一个Document对象 Document doc = db.parse("books.xml"); NodeList bookList = doc.getElementsByTagName("book"); // 获取节点个数 System.out.println("一共有" + bookList.getLength() + "本书"); // 遍历每个book节点 for (int i = 0; i < bookList.getLength(); i++) { System.out.println("*******************************"); // 索引从零开始 org.w3c.dom.Node book = bookList.item(i); // 获取book节点所有属性集合 org.w3c.dom.NamedNodeMap attrs = book.getAttributes(); System.out.println("第" + (i + 1) + "本书共有" + attrs.getLength() + "属性"); // 遍历book属性,不知道节点属性和属性名情况 for (int j = 0; j < attrs.getLength(); j++) { // 获取某一个属性 org.w3c.dom.Node attr = attrs.item(j); System.out.print("属性名:" + attr.getNodeName()); System.out.println(" --- 属性值:" + attr.getNodeValue()); } // 若已经知道book节点有且只有1个ID属性,可用以下方式 // org.w3c.dom.Element e = (org.w3c.dom.Element) // bookList.item(i); // System.out.println("Element属性值:"+e.getAttribute("id")); NodeList childNodes = book.getChildNodes(); for (int k = 0; k < childNodes.getLength(); k++) { // 区分,去掉空格和换行符 if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) { // 获取element类型的节点和节点值 System.out.print("节点名:" + childNodes.item(k).getNodeName()); System.out.print(" --- 节点值:" + childNodes.item(k).getFirstChild().getNodeValue()); System.out.println(" --- 节点值:"+childNodes.item(k).getTextContent()); } } } } catch (Exception e) { e.printStackTrace(); } } }
结果输出:
三、Dom4j读取
使用dom4j需要导入相关的jar包
import java.io.File; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class Dom4jReadXml { public static void main(String[] args) { readXml(); } public static void readXml(){ try { // 创建SAXReader对象 SAXReader reader = new SAXReader(); // 加载xml文件 Document dc= reader.read(new File("books.xml")); // 获取根节点 Element e = dc.getRootElement(); // 获取迭代器 Iterator it = e.elementIterator(); // 遍历迭代器,获取根节点信息 while(it.hasNext()){ Element book = (Element) it.next(); List<Attribute> atts= book.attributes(); // 获取book属性名和属性值 for (Attribute att : atts) { System.out.println("节点名:"+att.getName()+"节点值:"+att.getValue()); } Iterator itt = book.elementIterator(); while(itt.hasNext()){ Element b = (Element) itt.next(); System.out.println("属性名:"+b.getName()+"属性值:"+b.getText()); } } } catch (Exception e) { // TODO: handle exception } } }
结果输出:
四、JDom读取
使用jdom需要导入相关的jar包
import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import org.jdom.Attribute; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; public class JDomReadXml { public static void main(String[] args) { // readXml(); } @SuppressWarnings("unchecked") public static void readXml(){ List<Book> bList = new ArrayList<Book>(); try { // 创建一个SAXBuilder对象 SAXBuilder builder = new SAXBuilder(); // 创建一个输入流 InputStream in = new FileInputStream("books.xml"); // 处理乱码情况 InputStreamReader isr = new InputStreamReader(in, "UTF-8"); // 通过build方法,将输入流加载到SAXBuilder中 Document doc = builder.build(isr); // 通过Document对象获取根节点 Element foo= doc.getRootElement(); // 获取根节点下子节点名 List<Element> allChildren = foo.getChildren(); // 进行解析 for (Element book : allChildren) { Book b = new Book(); System.out.println("开始解析第"+(allChildren.indexOf(book)+1)+"本书"); // 解析book属性集合 List<Attribute> attrList = book.getAttributes(); // 遍历(针对不清楚节点下属性名) for (Attribute attr : attrList) { System.out.println("属性名:"+attr.getName() +" -- 属性值:"+attr.getValue()); if("id".equals(attr.getName())){ b.setId(attr.getValue()); } } // 清楚知道属性名获取属性值 String v = book.getAttributeValue("id"); System.out.println("清楚知道属性名"+v); // 对book节点子节点的节点名和节点值进行遍历 List<Element> bookChiles = book.getChildren(); for (Element element : bookChiles) { System.out.println("属性名:"+element.getName() +" -- 属性值:"+element.getValue()); if("name".equals(element.getName())){ b.setName(element.getValue()); }else if("author".equals(element.getName())){ b.setAuthor(element.getValue()); }else if("year".equals(element.getName())){ b.setYear(element.getValue()); }else if("price".equals(element.getName())){ b.setPrice(element.getValue()); }else if("language".equals(element.getName())){ b.setLanguage(element.getValue()); } } System.out.println("结束解析第"+(allChildren.indexOf(book)+1)+"本书"); bList.add(b); b = null; } } catch (Exception e) { e.printStackTrace(); } } }
结果输出:
五、Sax读取
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class SaxReadXml { public static void main(String[] args) { readXml(); } public static void readXml() { try { // 创建工厂 SAXParserFactory sf=SAXParserFactory.newInstance(); // 获取SAXParser实例 SAXParser sp = sf.newSAXParser(); // 创建一个解析对象 SAXParserHandler handler = new SAXParserHandler(); sp.parse("books.xml", handler); for(Book book : handler.getbList()){ System.out.println(book.getId()); System.out.println(book.getName()); System.out.println(book.getAuthor()); System.out.println(book.getYear()); System.out.println(book.getPrice()); System.out.println(book.getLanguage()); System.out.println("*****************"); } } catch (Exception e) { e.printStackTrace(); } } }
SAXParserHandler .java
import java.util.ArrayList; import java.util.List; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class SAXParserHandler extends DefaultHandler { int bookIndex = 0; String str = null; Book b = null; private List<Book> bList = new ArrayList<Book>(); public List<Book> getbList() { return bList; } /** * 用来遍历xml文件的开始标签 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // 调用DefaultHandler的startElement方法 super.startElement(uri, localName, qName, attributes); // 开始解析book元素属性 if(qName.equals("book")){ bookIndex++; // 创建一个book对象 b = new Book(); System.out.println("****开始第"+bookIndex+"本书内容****"); // 已知book元素下属性名称,根据属性名称获取属性值s String value = attributes.getValue("id"); System.out.println("book的属性值是:"+value); int num = attributes.getLength(); for(int i=0;i<num;i++){ System.out.print("book元素的第"+(i+1)+"个属性名是:"+attributes.getQName(i)); System.out.println(" -- 属性值是:"+attributes.getValue(i)); if(attributes.getQName(i).equals("id")){ b.setId(attributes.getQName(i)); } } }else if(!qName.equals("book") && !qName.equals("bookstore")){ System.out.print("节点名是:"+qName); } } /** * 用来遍历xml文件的结束标签 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { // 调用DefaultHandler的endElement方法 super.endElement(uri, localName, qName); // 判断是否针对一本书已经遍历结束 if(qName.equals("book")){ bList.add(b); b = null; System.out.println("****结束第"+bookIndex+"本书内容****"); }else if(qName.equals("name")){ b.setName(str); }else if(qName.equals("author")){ b.setAuthor(str); }else if(qName.equals("year")){ b.setYear(str); }else if(qName.equals("price")){ b.setPrice(str); }else if(qName.equals("language")){ b.setLanguage(str); } } /** * 用来标志解析开始 */ @Override public void startDocument() throws SAXException { // 调用DefaultHandler的startDocument方法 super.startDocument(); System.out.println("解析开始"); } /** * 用来标志解析结束 */ @Override public void endDocument() throws SAXException { // 调用DefaultHandler的endDocument方法 super.endDocument(); System.out.println("解析结束"); } /** * 用来标志解析结束 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { // 调用DefaultHandler的characters方法 super.characters(ch, start, length); str = new String(ch, start, length); if(!str.trim().equals("")){ System.out.println(" -- 节点值是:"+str); } } }
结果输出:
六、附赠properties的读取
在src文件中新建文件dataBase.properties
在文件中写入projectName=\u6D4B\u8BD5\u9879\u76EE
public class ReadProperties { public static void main(String[] args){ System.out.println(getProjectName()); } public static String getProjectName() { Properties pro = new Properties(); try { // 获取文件内容 InputStream cp = ReadProperties.class.getResourceAsStream("/dataBase.properties"); // 加载 pro.load(cp); // 获取projectName属性 return pro.getProperty("projectName"); } catch (Exception e) { e.printStackTrace(); return "出错了"; } } }
结果输出:测试项目
七、总结
* dom平台无关,官方解析方式,一次性加载,方便解析,代码容易编写,当文件过大,容易造成内存溢出 * sax基于事件驱动的解析方式,加载时进行验证判断,内存耗费小,不易编码,很难同时访问一个xml中的多处不同数据 * * jdom和dom4j是基于sax扩展 * * jdom仅使用具体类而不使用接口,api中大量使用了collections类 * * dom4j是jdom的一种智能分支,具有性能优异,灵活性好,功能强大和易使用的特点