标签:
.xml文件,树形结构
标准XML文档示例:
<?xml version="1.0" encoding="UTF-8"?>
<bookStore>
<book id="1">
<name>冰与火之歌</name>
<author>乔治马丁</author>
<year>2014</year>
<price>99</price>
</book>
<book id="2">
<name>秦腔</name>
<author>贾平凹</author>
<price>90</price>
</book>
</bookStore>
Why?:
1、不同应用程序之间的通信问题(订票软件和支付软件);
2、不同平台间的通信(MAC和windows);
3、不同平台间共享数据(PC端和移动端)
JAVA读取XML(解析)
目的:
获取节点名、节点值、属性名、属性值。解析后JAVA程序能够得到XML文件的所有数据
四种方式:
DOM(官方)
SAX(官方)
DOM4J(需要导jar包)
JDOM(需要导jar包)
books.xml文件练习:
DOM解析
将xml文件全部加载到内存,然后逐个解析。
常用节点类型
解析方法:
package DomTest;
import java.io.IOException;
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 DOMTest {
public static void main(String[] args) {
// 创建一个DocumentBuilderFactory对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建一个DocumentBuilder的对象
try {
// 创建DocumentBuilder对象
DocumentBuilder db = dbf.newDocumentBuilder();
// 通过DocumentBuilder对象的parse方法加载books.xml文件
// 到当前项目下
Document document = db.parse("books.xml");
// 获取所有book节点的集合
NodeList bookList = document.getElementsByTagName("book");
//通过nodeList的getLength()方法获取bookLIst的长度
System.out.println("一共有:"+bookList.getLength()+"本书");
//便利各个book节点
for (int i = 0; i < bookList.getLength(); i++) {
System.out.println("开始遍历第"+(i+1)+"本书");
//通过 item(i)获取一个book节点,nodeList
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()方法获取book节点的某一个属性
Node attr=attrs.item(j);
//获取属性名
System.out.println("属性名:"+attr.getNodeName());
//获取属性值
System.out.println("属性值:"+attr.getNodeValue());
}
System.out.println("结束遍历第"+(i+1)+"本书");
}
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
}
}
输出:
一共有:2本书
开始遍历第1本书
第1本书共有1个属性
属性名:id
属性值:1
结束遍历第1本书
开始遍历第2本书
第2本书共有1个属性
属性名:id
属性值:2
结束遍历第2本书
已知节点属性名称的情况下的遍历:
package DomTest;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DOMTest {
public static void main(String[] args) {
// 创建一个DocumentBuilderFactory对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建一个DocumentBuilder的对象
try {
// 创建DocumentBuilder对象
DocumentBuilder db = dbf.newDocumentBuilder();
// 通过DocumentBuilder对象的parse方法加载books.xml文件
// 到当前项目下
Document document = db.parse("books.xml");
// 获取所有book节点的集合
NodeList bookList = document.getElementsByTagName("book");
//通过nodeList的getLength()方法获取bookLIst的长度
System.out.println("一共有:"+bookList.getLength()+"本书");
//便利各个book节点
for (int i = 0; i < bookList.getLength(); i++) {
System.out.println("++++++++++++开始遍历第"+(i+1)+"本书+++++++++++");
//方式一,不知道有多少节点,通过循环来遍历所有节点。
// //通过 item(i)获取一个book节点,nodeList
// 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()方法获取book节点的某一个属性
// Node attr=attrs.item(j);
// //获取属性名
// System.out.println("属性名:"+attr.getNodeName());
// //获取属性值
// System.out.println("属性值:"+attr.getNodeValue());
// }
//方式二,知道有且只有一个节点。并且知道属性的名称为“id”
//强制类型转换将book节点类型转换为Element类型
Element book =(Element) bookList.item(i);
//通过getAttribute(“id”)方法获取到属性的值
String attrValue=book.getAttribute("id");
System.out.println("id的属性的属性值为"+attrValue);
// //解析book节点的子节点,需要用到方式一中创建的book对象
// //获取子节点的集合
// NodeList childNodes=book.getChildNodes();
//
// //遍历childNodes获取每个子节点的节点名和节点值
// System.out.println("第"+(i+1)+"本书共有"+childNodes.getLength()+"个子节点");
//
System.out.println("++++++++++++结束遍历第"+(i+1)+"本书++++++++++++");
}
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
}
}
输出:
一共有:2本书
++++++++++++开始遍历第1本书+++++++++++
id的属性的属性值为1
++++++++++++结束遍历第1本书++++++++++++
++++++++++++开始遍历第2本书+++++++++++
id的属性的属性值为2
++++++++++++结束遍历第2本书++++++++++++
解析book节点下的所有子节点:
package DomTest;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DOMTest {
public static void main(String[] args) {
// 创建一个DocumentBuilderFactory对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建一个DocumentBuilder的对象
try {
// 创建DocumentBuilder对象
DocumentBuilder db = dbf.newDocumentBuilder();
// 通过DocumentBuilder对象的parse方法加载books.xml文件
// 到当前项目下
Document document = db.parse("books.xml");
// 获取所有book节点的集合
NodeList bookList = document.getElementsByTagName("book");
//通过nodeList的getLength()方法获取bookLIst的长度
System.out.println("一共有:"+bookList.getLength()+"本书");
//便利各个book节点
for (int i = 0; i < bookList.getLength(); i++) {
System.out.println("++++++++++++开始遍历第"+(i+1)+"本书+++++++++++");
//方式一,不知道有多少节点,通过循环来遍历所有节点。
//通过 item(i)获取一个book节点,nodeList
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()方法获取book节点的某一个属性
Node attr=attrs.item(j);
//获取属性名
System.out.println("属性名:"+attr.getNodeName());
//获取属性值
System.out.println("属性值:"+attr.getNodeValue());
}
// //方式二,知道有且只有一个节点。并且知道属性的名称为“id”
// //强制类型转换将book节点类型转换为Element类型
// Element book =(Element) bookList.item(i);
//
// //通过getAttribute(“id”)方法获取到属性的值
// String attrValue=book.getAttribute("id");
// System.out.println("id的属性的属性值为"+attrValue);
//解析book节点的子节点,需要用到方式一中创建的book对象
//获取子节点的集合
NodeList childNodes=book.getChildNodes();
//遍历childNodes获取每个子节点的节点名和节点值
System.out.println("第"+(i+1)+"本书共有"+childNodes.getLength()+"个子节点");
//循环遍历
for (int j = 0; j < childNodes.getLength(); j++) {
//区分text类型的node和element类型的node
if(childNodes.item(j).getNodeType()==Node.ELEMENT_NODE){
//输出了element类型节点的节点名
System.out.println("第"+(j+1)+"个节点名:"+childNodes.item(j).getNodeName());
//输出element类型节点的节点值
//需先获取当前节点的首个子节点,否则获取的是《name》标签的值NULL
//方式一:如果<name>节点下有多个子节点,此方法只输出确定的某个子节点的值
//同样要注意,<name>节点的第一个子节点的值是第一子节点的类型的值,还是NULL
System.out.println("节点值为:"+childNodes.item(j).getFirstChild()
.getNodeValue());
//方式二:如果<name>节点下有多个子节点,此方法输出所有子节点的text
System.out.println(childNodes.item(j).getTextContent());
}
}
System.out.println("++++++++++++结束遍历第"+(i+1)+"本书++++++++++++");
}
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
}
}
输出:
一共有:2本书
++++++++++++开始遍历第1本书+++++++++++
第1本书共有1个属性
属性名:id
属性值:1
第1本书共有9个子节点
第2个节点名:name
节点值为:冰与火之歌
冰与火之歌
第4个节点名:author
节点值为:乔治马丁
乔治马丁
第6个节点名:year
节点值为:2014
2014
第8个节点名:price
节点值为:99
99
++++++++++++结束遍历第1本书++++++++++++
++++++++++++开始遍历第2本书+++++++++++
第2本书共有1个属性
属性名:id
属性值:2
第2本书共有7个子节点
第2个节点名:name
节点值为:秦腔
秦腔
第4个节点名:author
节点值为:贾平凹
贾平凹
第6个节点名:price
节点值为:90
90
++++++++++++结束遍历第2本书++++++++++++
SAX解析XML文件
通过自己创建的一个Handler类,由外向内顺序逐个解析。
初步解析:
步骤:
1、通过SAXParseFactory的静态newInstance()方法获取SAXParseFactory实例factory
2、通过SAXParserFactory实例的newSAXParser()方法返回SAXParse实例parser
3、创建一个类继承DefaultHandler,重写其中的一些方法进行业务处理并创建这个类的实例handler
重写两个方法:
startElement()
endElement()
SAXParserHandler:
package test2;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXParserHandler extends DefaultHandler {
/***
* 遍历xml的开始标签
*/
@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);
}
/***
* 遍历xml的结束标签
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
}
/***
* 标识解析开始
*/
@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解析结束");
}
}
SAXTest.java:
package test;
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 test2.SAXParserHandler;
public class SAXTest {
public static void main(String[] args) {
// 通过SAXParseFactory的静态newInstance()
//方法获取SAXParseFactory实例factory
SAXParserFactory factory=SAXParserFactory.newInstance();
//通过SAXParserFactory实例的newSAXParser()
//方法返回SAXParse实例parser
try {
SAXParser parser= factory.newSAXParser();
//创建SAXParserHandler对象
SAXParserHandler handler=new SAXParserHandler();
parser.parse("books.xml", handler);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException | SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行输出:
SAX解析开始
SAX解析结束
解析节点属性:
package test2;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import test3.Book;
public class SAXParserHandler extends DefaultHandler {
int bookIndex=0;//显示是第几本书的变量
/***
* 遍历xml的开始标签
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
//调用DefaultHandler类的startElement方法
super.startElement(uri, localName, qName, attributes);
//开始解析book元素的属性
if (qName.equals("book")) {
bookIndex++;
System.out.println("开始遍历第"+bookIndex+"本书");
// //方法一:已知book元素下属性的名称,根据属性名称获取属性的值。
// String value=attributes.getValue("id");
// System.out.println("book的属性值为:"+value);
//方法二:book元素下舒心规定名称个数未知的情况
int num=attributes.getLength();
for (int i = 0; i < num; i++) {
System.out.println("book元素的第"+(i+1)
+"个属性名:"+attributes.getQName(i));
System.out.println("book元素的第"+(i+1)
+"个属性值:"+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);
}
//qName.equals("name")时,向book中setName()
}
/***
* 遍历xml的结束标签
*/
@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")) {
System.out.println("遍历结束");
System.out.println("结束遍历第"+bookIndex+"本书");
System.out.println();
}
}
/***
* 标识解析开始
*/
@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解析结束");
}
/***
* ch 节点中的所有内容
* start 开始的节点
*
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
String value=new String(ch,start,length);
if (!value.trim().equals("")) {
System.out.println("\t节点值是:"+value);
}
}
}
输出:
SAX解析开始
开始遍历第1本书
book元素的第1个属性名:id
book元素的第1个属性值:1
节点名是:name 节点值是:冰与火之歌
节点名是:author 节点值是:乔治马丁
节点名是:year 节点值是:2014
节点名是:price 节点值是:99
遍历结束
结束遍历第1本书
开始遍历第2本书
book元素的第1个属性名:id
book元素的第1个属性值:2
节点名是:name 节点值是:秦腔
节点名是:author 节点值是:贾平凹
节点名是:price 节点值是:90
遍历结束
结束遍历第2本书
SAX解析结束
解析并存储XML结构:
新建Book类
package test3;
public class Book {
private String id;
private String name;
private String author;
private String year;
private String price;
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 getAuthor() {
return author;
}
public void setAuthor(String autor) {
this.author = autor;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
修改SAXParserHandler:
package test2;
import java.util.ArrayList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import test3.Book;
public class SAXParserHandler extends DefaultHandler {
int bookIndex=0;//显示是第几本书的变量
//将character()中的value定义为全局变量
String value=null;
Book book=null;
private ArrayList<Book> bookList=new ArrayList<Book>();
public ArrayList<Book> getBookList(){
return bookList;
}
/***
* 遍历xml的开始标签
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
//调用DefaultHandler类的startElement方法
super.startElement(uri, localName, qName, attributes);
//开始解析book元素的属性
if (qName.equals("book")) {
book=new Book();
bookIndex++;
System.out.println("开始遍历第"+bookIndex+"本书");
// //方法一:已知book元素下属性的名称,根据属性名称获取属性的值。
// String value=attributes.getValue("id");
// System.out.println("book的属性值为:"+value);
//方法二:book元素下舒心规定名称个数未知的情况
int num=attributes.getLength();
for (int i = 0; i < num; i++) {
System.out.println("book元素的第"+(i+1)
+"个属性名:"+attributes.getQName(i));
System.out.println("book元素的第"+(i+1)
+"个属性值:"+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);
}
//qName.equals("name")时,向book中setName()
}
/***
* 遍历xml的结束标签
*/
@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(book);
book=null;
System.out.println("遍历结束");
System.out.println("结束遍历第"+bookIndex+"本书");
System.out.println();
}else if(qName.equals("name")){
book.setName(value);
}else if(qName.equals("author")){
book.setAuthor(value);
}else if(qName.equals("year")){
book.setYear(value);
}else if(qName.equals("price")){
book.setPrice(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解析结束");
}
/***
* ch 节点中的所有内容
* start 开始的节点
*
*/
@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);
if (!value.trim().equals("")) {
System.out.println("\t节点值是:"+value);
}
}
}
修改SAXTest:
package test;
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 test2.SAXParserHandler;
import test3.Book;
public class SAXTest {
public static void main(String[] args) {
// 通过SAXParseFactory的静态newInstance()
//方法获取SAXParseFactory实例factory
SAXParserFactory factory=SAXParserFactory.newInstance();
//通过SAXParserFactory实例的newSAXParser()
//方法返回SAXParse实例parser
try {
SAXParser parser= factory.newSAXParser();
//创建SAXParserHandler对象
SAXParserHandler handler=new SAXParserHandler();
parser.parse("books.xml", handler);
System.out.println("书的数量:"+handler.getBookList().size());
for(Book book: handler.getBookList()){
System.out.println(book.getId());
System.out.println(book.getName());
System.out.println(book.getAuthor());
System.out.println(book.getPrice());
System.out.println(book.getYear());
System.out.println("-------------");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException | SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出:
SAX解析开始
开始遍历第1本书
book元素的第1个属性名:id
book元素的第1个属性值:1
节点名是:name 节点值是:冰与火之歌
节点名是:author 节点值是:乔治马丁
节点名是:year 节点值是:2014
节点名是:price 节点值是:99
遍历结束
结束遍历第1本书
开始遍历第2本书
book元素的第1个属性名:id
book元素的第1个属性值:2
节点名是:name 节点值是:秦腔
节点名是:author 节点值是:贾平凹
节点名是:price 节点值是:90
遍历结束
结束遍历第2本书
SAX解析结束
书的数量:2
1
冰与火之歌
乔治马丁
99
2014
2
秦腔
贾平凹
90
null
JDOM解析
包文件夹右键,Build Path,Add External Archices 导入JDOM jar包,但只是引用了路径,无法迁移到其他设备。
解决办法:在项目文件夹下新建一个文件夹,将jar包放进新建的文件夹之后再重新导入。右键jar包, Build Path》》》Add Path
package test;
import java.util.List;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
public class JDOMTest {
public static void main(String[] args) {
//JDOM解析XML文件
//创建一个SAXBuilder对象
SAXBuilder saxbuilder=new SAXBuilder();
InputStream in;
try {
//创建一个输入流,将xml文件加载到流中
in = new FileInputStream("src/res/books.xml");
//通过saxbuilder的build方法将输入流加载到saxbuilder中
Document document= saxbuilder.build(in);
//通过document对象获取xml文件的根节点
Element rootElement= document.getRootElement();
//获取根节点下的子节点的集合
List<Element> bookList=rootElement.getChildren();
//使用foreach循环解析
for (Element book : bookList) {
System.out.println("开始解析第"+(bookList.indexOf(book)+1)
+"本书============");
//解析book的属性
List<Attribute> attrList=book.getAttributes();
// //知道节点属性名
// book.getAttribute("id");
//针对不清楚book节点下属性名和数量的情况
//遍历attrList
for (Attribute attr : attrList) {
//获取属性名和属性值
String attrName=attr.getName();
String attrValue=attr.getValue();
System.out.println("属性名:"+attrName+"\t属性值:"+attrValue);
}
//对book节点的子节点的节点名和节点值进行遍历
List<Element> bookChilds= book.getChildren();
for (Element child : bookChilds) {
System.out.println("节点名:"+child.getName()+"\t节点值:"+child.getValue());
}
System.out.println("结束解析第"+(bookList.indexOf(book)+1)
+"本书============");
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.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 节点值:冰与火之歌
节点名:author 节点值:乔治马丁
节点名:year 节点值:2014
节点名:price 节点值:99
结束解析第1本书============
开始解析第2本书============
属性名:id 属性值:2
节点名:name 节点值:秦腔
节点名:author 节点值:贾平凹
节点名:price 节点值:90
结束解析第2本书============
如果解析出来中文出现乱码情况,修改XML文件第一行的encoding属性。如果修改无效,再继续在java代码中进行修改操作。创建InputStreamReader对象并直接制定字符编码:
InputStreamReader ins=new InputStreamReader(in,"UTF-8");
加入存储Book对象的操作:
package test;
import java.util.ArrayList;
import java.util.List;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import test3.Book;
public class JDOMTest {
private static ArrayList<Book> booksList=new ArrayList<Book>();
public static void main(String[] args) {
//JDOM解析XML文件
//创建一个SAXBuilder对象
SAXBuilder saxbuilder=new SAXBuilder();
InputStream in;
try {
//创建一个输入流,将xml文件加载到流中
in = new FileInputStream("src/res/books.xml");
// InputStreamReader ins=new InputStreamReader(in,"UTF-8");
//通过saxbuilder的build方法将输入流加载到saxbuilder中
Document document= saxbuilder.build(in);
//通过document对象获取xml文件的根节点
Element rootElement= document.getRootElement();
//获取根节点下的子节点的集合
List<Element> bookList=rootElement.getChildren();
//使用foreach循环解析
for (Element book : bookList) {
Book bookEntity=new Book();
System.out.println("开始解析第"+(bookList.indexOf(book)+1)
+"本书============");
//解析book的属性
List<Attribute> attrList=book.getAttributes();
// //知道节点属性名
// book.getAttribute("id");
//针对不清楚book节点下属性名和数量的情况
//遍历attrList
for (Attribute attr : attrList) {
//获取属性名和属性值
String attrName=attr.getName();
String attrValue=attr.getValue();
System.out.println("属性名:"+attrName+"\t属性值:"+attrValue);
//存储book节点
if(attrName.equals("id")){
bookEntity.setId(attrValue);
}
}
//对book节点的子节点的节点名和节点值进行遍历
List<Element> bookChilds= book.getChildren();
for (Element child : bookChilds) {
System.out.println("节点名:"+child.getName()+"\t节点值:"+child.getValue());
//存储子节点名
if(child.getName().equals("name")){
bookEntity.setName(child.getValue());
}else if(child.getName().equals("author")){
bookEntity.setAuthor(child.getValue());
}else if(child.getName().equals("year")){
bookEntity.setYear(child.getValue());
}else if(child.getName().equals("price")){
bookEntity.setPrice(child.getValue());
}
}
System.out.println("结束解析第"+(bookList.indexOf(book)+1)
+"本书============");
//添加booksList集合对象
booksList.add(bookEntity);
bookEntity=null;
System.out.println(booksList.size());
System.out.println(booksList.get(0).getId());
System.out.println(booksList.get(0).getName());
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.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 节点值:冰与火之歌
节点名:author 节点值:乔治马丁
节点名:year 节点值:2014
节点名:price 节点值:99
结束解析第1本书============
1
1
冰与火之歌
开始解析第2本书============
属性名:id 属性值:2
节点名:name 节点值:秦腔
节点名:author 节点值:贾平凹
节点名:price 节点值:90
结束解析第2本书============
2
1
冰与火之歌
DOM4J解析:
先导入DOM4J jar包
package 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 DOM4JTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建SAXReader对象
SAXReader reader=new SAXReader();
//通过reader对象read 方法加载book.xml
try {
Document document=reader.read(new File("src/res/books.xml"));
//通过document对象获取根节点bookstore
Element bookStore=document.getRootElement();
//通过element对象的elementIterator方法获取迭代器
Iterator it=bookStore.elementIterator();
//遍历迭代器,获取根节点中的信息
while(it.hasNext()){
System.out.println("开始遍历一本书");
Element book=(Element) it.next();
//获取book的属性名和属性值
List<Attribute> bookAttrs=book.attributes();
for (Attribute attr : bookAttrs) {
System.out.println("属性名:"+attr.getName()
+"\t属性值:"+attr.getValue());
}
Iterator itt=book.elementIterator();
while(itt.hasNext()){
Element bookChild=(Element) itt.next();
System.out.println("节点名:"+bookChild.getName()+
"\t节点值:"+bookChild.getStringValue());
}
System.out.println("结束遍历一本书"+"\n");
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出:
开始遍历一本书
属性名:id 属性值:1
节点名:name 节点值:冰与火之歌
节点名:author 节点值:乔治马丁
节点名:year 节点值:2014
节点名:price 节点值:99
结束遍历一本书
开始遍历一本书
属性名:id 属性值:2
节点名:name 节点值:秦腔
节点名:author 节点值:贾平凹
节点名:price 节点值:90
结束遍历一本书
四种解析方式对比:
基础:
DOM(跨平台)、一次性加载全部XML。
优点:形成了树结构,直观显示,代码编写简单;解析过程中树结构保留在内存中,便于修改。
缺点:XML文件较大时,太耗内存,影响解析操作并造成内存溢出。
SAX(基于事件驱动的解析方式)逐行读取解析
优点:占内存小,适用于只处理XML中的数据。
缺点:不易编码,很难同时访问同一个XML中的多出不同数据。
扩展(仅在JAVA平台使用):JDOM仅使用具体类而不是接口,API大量使用了Cillections类。
DOM4J、是JDOM的一种只能分支。合并了很多超出基本XML文档表示的功能;使用接口和抽象基本类;具有灵活性好,性能特异,功能强大和极端易用的特点。开源软件。
标签:
原文地址:http://blog.csdn.net/u014102097/article/details/51547591