首先创建一个xml文档,文档内容如下
<?xml version="1.0" encoding="UTF-8"?> <bookstore> <book id="1"> <name>编程之美</name> <price>34.0</price> <author>《编程之美》小组</author> </book> <book id="2"> <name>平凡的世界</name> <price>56.0</price> <author>路遥</author> <language>中文</language> </book> </bookstore>
因为xml定义是书店的书本详情,解析完xml之后,希望把解析之后的数据保存下来,所以定义了一个Book的Entity,定义好各个属性
package com.ikok.parsexml; public class Book { private String id; private String name; private String price; private String author; private String language; 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 getPrice() { return price; } public void setPrice(String price) { this.price = price; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getLanguage() { return language; } public void setLanguage(String language) { this.language = language; } }
package com.ikok.parsexml; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class domXml { private static List<Book> booksList = new ArrayList<Book>(); public static void main(String[] args) { // 创建一个DocumentBuilderFactory对象 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { // 创建一个DocumentBuilder对象 DocumentBuilder db = dbf.newDocumentBuilder(); // 通过DocumentBuilder对象的parse方法加载xml文件到当前项目 Document document = db.parse("books.xml"); // 获取所有book节点的集合 NodeList bookList = document.getElementsByTagName("book"); // 遍历每一个book节点,通过bookList.getLength()方法知道集合的长度 System.out.println("一共有 " + bookList.getLength() + " 本书"); for (int i = 0; i < bookList.getLength(); i++) { Book bookItem = new Book(); System.out.println("-----------开始遍历第" + (i+1) + "本书的内容-----------"); // 通过item(i)的方法获取一个book节点,NodeList的索引值从0开始 Node book = bookList.item(i); // 获取book节点的所有属性集合 NamedNodeMap attrs = book.getAttributes(); System.out.println("第 " + (i+1) + " 本书共有 " + attrs.getLength() + " 个属性"); // 遍历book的属性 for (int j = 0; j < attrs.getLength(); j++) { // 通过item(i)的方法获取一个book节点的某个属性 Node attr = attrs.item(j); // 获取属性名 System.out.print("属性名为:" + attr.getNodeName()); // 获取属性值 System.out.println("----属性值为:" + attr.getNodeValue()); if(attr.getNodeName().equals("id")){ bookItem.setId(attr.getNodeValue()); } } // 当知道节点有且只有一个属性时,进行强制类型转换,通过getAttribute()方法获取属性值 // Element book = (Element) bookList.item(i); // String attrValue = book.getAttribute("id"); // System.out.println("id :" + attrValue); //解析book节点的子节点 NodeList childList = book.getChildNodes(); System.out.println("第 " + (i+1) + " 本书共有 " + childList.getLength() + " 个子节点"); for (int k = 0; k < childList.getLength(); k++) { // 区分出text类型的node以及element类型node if (childList.item(k).getNodeType() == Node.ELEMENT_NODE) { // 获取了element类型节点的节点名 System.out.print("第 " + (i+1) + " 本书的子节点名: " + childList.item(k).getNodeName() + "----"); // 如果当前节点中还有节点,则属性值为空。比如<name><a>aa</a><b>bb</b>第一行代码</name> System.out.println(" 属性值: " + childList.item(k).getFirstChild().getNodeValue()); // 这样会输出所有子节点和节点之间的内容。会输出 aabb第一行代码 // System.out.println(childList.item(k).getTextContent()); if(childList.item(k).getNodeName().equals("name")){ bookItem.setName(childList.item(k).getFirstChild().getNodeValue()); } else if(childList.item(k).getNodeName().equals("price")){ bookItem.setPrice(childList.item(k).getFirstChild().getNodeValue()); } else if(childList.item(k).getNodeName().equals("author")){ bookItem.setAuthor(childList.item(k).getFirstChild().getNodeValue()); } else if(childList.item(k).getNodeName().equals("language")){ bookItem.setLanguage(childList.item(k).getFirstChild().getNodeValue()); } } } System.out.println("-----------结束遍历第" + (i+1) + "本书的内容-----------"); System.out.println(); booksList.add(bookItem); bookItem = null; } for (Book item : booksList) { System.out.println("书本id :" + item.getId()); System.out.println("书本名字 :" + item.getName()); System.out.println("书本价格 :" + item.getPrice()); System.out.println("书本作者 :" + item.getAuthor()); System.out.println("书本语言 :" + item.getLanguage()); System.out.println("---------------------------------"); } } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }结果:
一共有 2 本书 -----------开始遍历第1本书的内容----------- 第 1 本书共有 1 个属性 属性名为:id----属性值为:1 第 1 本书共有 7 个子节点 第 1 本书的子节点名: name---- 属性值: 编程之美 第 1 本书的子节点名: price---- 属性值: 34.0 第 1 本书的子节点名: author---- 属性值: 《编程之美》小组 -----------结束遍历第1本书的内容----------- -----------开始遍历第2本书的内容----------- 第 2 本书共有 1 个属性 属性名为:id----属性值为:2 第 2 本书共有 9 个子节点 第 2 本书的子节点名: name---- 属性值: 平凡的世界 第 2 本书的子节点名: price---- 属性值: 56.0 第 2 本书的子节点名: author---- 属性值: 路遥 第 2 本书的子节点名: language---- 属性值: 中文 -----------结束遍历第2本书的内容----------- 书本id :1 书本名字 :编程之美 书本价格 :34.0 书本作者 :《编程之美》小组 书本语言 :null --------------------------------- 书本id :2 书本名字 :平凡的世界 书本价格 :56.0 书本作者 :路遥 书本语言 :中文 ---------------------------------
SAX解析:
package com.ikok.parsexml; import java.io.IOException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; public class SAXXml { public static void main(String[] args) { // 创建一个SAXParserFactory的实例 SAXParserFactory saxpf = SAXParserFactory.newInstance(); try { // 通过SAXParserFactory的实例获取SAXParser的实例 SAXParser parser = saxpf.newSAXParser(); SAXParserHandler handler = new SAXParserHandler(); parser.parse("books.xml", handler); System.out.println("共有 " + handler.getBookList().size() + " 本书"); for (Book book : handler.getBookList()) { System.out.println("书本id :" + book.getId()); System.out.println("书本名字 :" + book.getName()); System.out.println("书本价格 :" + book.getPrice()); System.out.println("书本作者 :" + book.getAuthor()); System.out.println("书本语言 :" + book.getLanguage()); System.out.println("---------------------------------"); } } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package com.ikok.parsexml; 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; /** * 某个属性值 * 因为属性名在startElement()方法中得到,而属性值却在characters()方法中得到 * 为了能把属性名和属性值加到book实例中去,在endElement()方法前,另外两个方法都执行了,所以在这进行处理 */ String value = null; Book book = null; private List<Book> bookList = new ArrayList<Book>(); public List<Book> getBookList() { return bookList; } // 用来遍历xml文件的开始标签 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); // 开始解析book元素的属性 if(qName.equals("book")){ // 创建一个book对象 book = new Book(); bookIndex++; System.out.println("-----------开始遍历第" + bookIndex + "本书的内容-----------"); // // 已知book元素下属性的名称,根据属性名获取属性值 // String value = attributes.getValue("id"); // System.out.println("id:" + value); // 不知道book元素下属性的名称以及个数,获取属性名及属性值 // 属性个数 int num = attributes.getLength(); for (int i = 0; i < num; i++) { System.out.print("第 " + (i+1) + "个属性名: " + attributes.getQName(i)); System.out.println(" 属性值: " + attributes.getValue(i)); if (attributes.getQName(i).equals("id")) { book.setId(attributes.getValue(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 { super.endElement(uri, localName, qName); // 针对一本书的内容是否遍历结束 if (qName.equals("book")) { // 清空book,方便执行下一个 bookList.add(book); book = null; System.out.println("-----------结束遍历第" + bookIndex + "本书的内容-----------"); } else if(qName.equals("name")){ book.setName(value); } else if(qName.equals("price")){ book.setPrice(value); } else if(qName.equals("author")){ book.setAuthor(value); } else if(qName.equals("language")){ book.setLanguage(value); } }; // 用来标志解析开始 @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub super.startDocument(); System.out.println("SAX解析开始"); } // 用来标志解析结束 @Override public void endDocument() throws SAXException { // TODO Auto-generated method stub super.endDocument(); System.out.println("SAX解析结束"); } @Override public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub super.characters(ch, start, length); // 获取了属性值 value = new String(ch, start, length); // 默认情况下,会把xml中的换行符也算进去,输出格式不正确,去掉换行符 if (!value.trim().equals("")) { System.out.println(value); } } }结果:
SAX解析开始 -----------开始遍历第1本书的内容----------- 第 1个属性名: id 属性值: 1 节点名:name 节点值:编程之美 节点名:price 节点值:34.0 节点名:author 节点值:《编程之美》小组 -----------结束遍历第1本书的内容----------- -----------开始遍历第2本书的内容----------- 第 1个属性名: id 属性值: 2 节点名:name 节点值:平凡的世界 节点名:price 节点值:56.0 节点名:author 节点值:路遥 节点名:language 节点值:中文 -----------结束遍历第2本书的内容----------- SAX解析结束 共有 2 本书 书本id :1 书本名字 :编程之美 书本价格 :34.0 书本作者 :《编程之美》小组 书本语言 :null --------------------------------- 书本id :2 书本名字 :平凡的世界 书本价格 :56.0 书本作者 :路遥 书本语言 :中文 ---------------------------------
package com.ikok.parsexml; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; 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; public class JdomXml { private static List<Book> bookList = new ArrayList<Book>(); public static void main(String[] args) { // 创建一个SAXBuilder对象 SAXBuilder saxbuilder = new SAXBuilder(); // 创建一个输入流,将xml加载到输入流中 InputStream is; try { is = new FileInputStream("books.xml"); // 防止解析乱码,将xml的encoding属性改为UTF-8,或者在代码中设置输入流的编码方式 // InputStreamReader isr = new InputStreamReader(is, "UTF-8"); // Document document = (Document) saxbuilder.build(isr); // 通过saxbuilder.build()方法,将输入流加载到saxbuilder中 Document document = (Document) saxbuilder.build(is); // 通过document对象获取xml的根节点 Element rootElement = document.getRootElement(); // 获取根节点下的子节点的集合 List<Element> elementList = rootElement.getChildren(); for (Element element : elementList) { Book book = new Book(); System.out.println("---------开始解析第" + (elementList.indexOf(element)+1) + "本书-----------------"); // // 知道属性的名字及个数 // System.out.println(element.getAttributeValue("id")); // 获取属性集合,不知道属性的名字及个数 List<Attribute> attrList = element.getAttributes(); for (Attribute attribute : attrList) { // 属性名 String attrName = attribute.getName(); // 属性值 String attrValue = attribute.getValue(); // 存储到Book中 if (attrName.equals("id")) { book.setId(attrValue); } System.out.println("属性名:" + attrName + "----属性值:" + attrValue); } // 对book节点下的子节点的节点名以及节点值进行解析 List<Element> childList = element.getChildren(); for (Element child : childList) { // 属性名 String attrName = child.getName(); // 属性值 String attrValue = child.getValue(); // 存储到Book中 if(attrName.equals("name")){ book.setName(attrValue); } else if(attrName.equals("price")){ book.setPrice(attrValue); } else if(attrName.equals("author")){ book.setAuthor(attrValue); } else if(attrName.equals("language")){ book.setLanguage(attrValue); } System.out.println("子节点名:" + attrName + "----子节点属性值:" + attrValue); } System.out.println("---------结束解析第" + (elementList.indexOf(element)+1) + "本书-----------------"); bookList.add(book); book = null; } for (Book item : bookList) { System.out.println("书本id :" + item.getId()); System.out.println("书本名字 :" + item.getName()); System.out.println("书本价格 :" + item.getPrice()); System.out.println("书本作者 :" + item.getAuthor()); System.out.println("书本语言 :" + item.getLanguage()); System.out.println("---------------------------------"); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (JDOMException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
结果:
---------开始解析第1本书----------------- 属性名:id----属性值:1 子节点名:name----子节点属性值:编程之美 子节点名:price----子节点属性值:34.0 子节点名:author----子节点属性值:《编程之美》小组 ---------结束解析第1本书----------------- ---------开始解析第2本书----------------- 属性名:id----属性值:2 子节点名:name----子节点属性值:平凡的世界 子节点名:price----子节点属性值:56.0 子节点名:author----子节点属性值:路遥 子节点名:language----子节点属性值:中文 ---------结束解析第2本书----------------- 书本id :1 书本名字 :编程之美 书本价格 :34.0 书本作者 :《编程之美》小组 书本语言 :null --------------------------------- 书本id :2 书本名字 :平凡的世界 书本价格 :56.0 书本作者 :路遥 书本语言 :中文 ---------------------------------
package com.ikok.parsexml; import java.io.File; import java.util.ArrayList; 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 dom4jXml { private static List<Book> bookList = new ArrayList<Book>(); // 书的序号 static int bookIndex = 0; public static void main(String[] args) { // 创建SAXReader的对象 SAXReader reader = new SAXReader(); try { // 通过reader的read()方法加载xml文件,获取document对象 Document document = reader.read(new File("books.xml")); // 获取根节点 Element rootElement = document.getRootElement(); // 获取迭代器 Iterator iterator = rootElement.elementIterator(); // 遍历迭代器,获取根节点中的信息 while (iterator.hasNext()) { bookIndex++; Book bookItem = new Book(); System.out.println("----------开始遍历第" + bookIndex + "本书------------"); Element book = (Element) iterator.next(); // 获取属性名和属性值 List<Attribute> attrList = book.attributes(); for (Attribute attr : attrList) { if(attr.getName().equals("id")){ bookItem.setId(attr.getValue()); } System.out.println("属性名:" + attr.getName() + "----属性值:" + attr.getValue()); } Iterator it = book.elementIterator(); while (it.hasNext()) { Element element = (Element) it.next(); if(element.getName().equals("name")){ bookItem.setName(element.getStringValue()); } else if(element.getName().equals("price")){ bookItem.setPrice(element.getStringValue()); } else if(element.getName().equals("author")){ bookItem.setAuthor(element.getStringValue()); } else if(element.getName().equals("language")){ bookItem.setLanguage(element.getStringValue()); } System.out.println("子节点名:" + element.getName() + "----子节点属性值:" + element.getStringValue()); } System.out.println("----------结束遍历第" + bookIndex + "本书------------"); bookList.add(bookItem); bookItem = null; } for (Book item : bookList) { System.out.println("书本id :" + item.getId()); System.out.println("书本名字 :" + item.getName()); System.out.println("书本价格 :" + item.getPrice()); System.out.println("书本作者 :" + item.getAuthor()); System.out.println("书本语言 :" + item.getLanguage()); System.out.println("---------------------------------"); } } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }结果:
----------开始遍历第1本书------------ 属性名:id----属性值:1 子节点名:name----子节点属性值:编程之美 子节点名:price----子节点属性值:34.0 子节点名:author----子节点属性值:《编程之美》小组 ----------结束遍历第1本书------------ ----------开始遍历第2本书------------ 属性名:id----属性值:2 子节点名:name----子节点属性值:平凡的世界 子节点名:price----子节点属性值:56.0 子节点名:author----子节点属性值:路遥 子节点名:language----子节点属性值:中文 ----------结束遍历第2本书------------ 书本id :1 书本名字 :编程之美 书本价格 :34.0 书本作者 :《编程之美》小组 书本语言 :null --------------------------------- 书本id :2 书本名字 :平凡的世界 书本价格 :56.0 书本作者 :路遥 书本语言 :中文 ---------------------------------
以当前这个XML为解析的目标的情况下,解析耗时,SAX耗时比DOM短,DOM4J耗时比JDOM短。
目前hibernate框架中也是使用的DOM4J解析XML。