version="1.0" encoding="utf-8">
id="1">
<name>冰与火之歌name>
乔治马丁
<year>2014year>
89
id="2">
<name>安徒生name>
乔治马丁
<year>2014year>
89
English
解析方式:DOM SAX DOM4J JDOM
节点类型 | NodeType | Named Constant | nodeName的返回值 | nodeValue的返回值 |
---|---|---|---|---|
Element | 1 | ELEMENT_NODE | element name | null |
Attr | 2 | ATTRIBUTE_NODE | 属性名称 | 属性值 |
Text | 3 | TEXT_NODE | text | 节点内容 |
public void nodePrase() throws Exception{
//1.创建一个DocumentBuilderFactory的对象
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
//2.创建一个DocumentBuider的对象
DocumentBuilder db=dbf.newDocumentBuilder();
//3.DocumentBuilder .parse()解析xml文件 得到document对象
Document document=db.parse("books.xml");
//4.获取所有book节点
NodeList bookList = document.getElementsByTagName("book");
//5.遍历每一个book节点
for(int i=0;i//6.通过item(i)获取每一本book节点 ,nodelist的索引从0开始
Node book = bookList.item(i);
//7.获取book的所有属性
NamedNodeMap attrs = book.getAttributes();
//8.遍历book属性
for(int j=0;j//9.获取属性名
String nodeName = attrs.item(j).getNodeName();
System.out.println(nodeName);
//10.获取属性值
String nodeValue = attrs.item(j).getNodeValue();
System.out.println(nodeValue);
}
//方式 二
//前题已经知道book节点有其只要一个id属性
//Element book = (Element) bookList.item(i); //强转成Element 可以调用 attributeValue("id") 直接拿到属性值
// String attrValue=book.attributeValue("id");
//解析book节点的子节点
NodeList childNodes=book.getChildNodes();
//遍历childNodes获取每个节点的 节点名和节点值 (空白和换行也会当成子节点)
for(int k=0;k//区分出text类型的Node以及element类型的node
if(childNodes.item(k).getNodeType()==Node.ELEMENT_NODE){
//获取element类型的节点名
String nodeName=childNodes.item(k).getNodeName();
System.out.println(nodeName);
//childNodes.item(k).getNodeValue();//为空
//String nodeValue = childNodes.item(k).getFirstChild().getNodeValue(); //节点里面的内容也被当成一个节点
String nodeValue = childNodes.item(k).getTextContent();//获取节点里面的所有文本值 (当该节点下子节点唯一时可以用,文本值唯一)
System.out.println(nodeValue);
}
}
}
}
1.通过SAXParserFactory的静态newInstance()方法获取SAXParserFactord的实例factory
2.通过SAXParserFactory实例获取SAXParser实例
3.创建SAXPraserHandler对象(需要重写 startDocument() endDocument() startElement() endElement()方法 )
4.解析xml文件
//如何保存book的节点信息呢
通过book的javabean对象来保存
//1.通过SAXParserFactory的静态newInstance()方法获取SAXParserFactord的实例factory
SAXParserFactory sf = SAXParserFactory.newInstance();
//2.通过SAXParserFactory实例获取SAXParser实例
SAXParser paser = sf.newSAXParser();
//3.创建SAXPraserHandler对象
SAXParserHandler ph = new SAXParserHandler();
//4.解析xml文件
paser.parse("books.xml", ph);
//5.获取ph中封装好的javabean对象
List
0.导入jar包
//对 books.xml文件进行JDOM解析
1.创建一个SAXBuilder的对象
2.创建一个输入流,将xml文件加载到输入流中
3.通过document对象获取xml文件的根节点
4.获取根节点下的子节点的List集合
private Book bk;//book的实体
private List list=new ArrayList();//存放解析后 生成的book实体
@Test
public void JDOMPrase() throws Exception{
//导入jar包
//对 books.xml文件进行JDOM解析
//1.创建一个SAXBuilder的对象
SAXBuilder saxBuilder=new SAXBuilder();
//2.创建一个输入流,将xml文件加载到输入流中
InputStream in=new FileInputStream("src/res/books.xml");
//解决乱码(用可以指定字符集的流进行包装)
InputStreamReader isr = new InputStreamReader(in, "utf-8");
Document document = saxBuilder.build(isr);
//3.通过document对象获取xml文件的根节点
Element rootElement = document.getRootElement();
//4.获取根节点下的子节点的List集合
List booklist = rootElement.getChildren();
//继续进行解析
for (Element book : booklist) {
System.out.println("-------------开始解析第"+(booklist.indexOf(book)+1)+"书-----------");
//解析book的属性
List attributes = book.getAttributes();
//知道属性名
//String attributeValue = book.getAttributeValue("id");
//System.out.println("");
//针对不清楚book节点下属性的名字及数量
for (Attribute attr : attributes) {
//创建book实体
bk =new Book();
//获取到属性名和属性值(都是有实际值的节点)
String name = attr.getName();
String value = attr.getValue();
System.out.println("属性名:"+name+"~"+"属性值:"+value);
//添加id
if("id".equals(name)){
bk.setId(value);
}
}
//对book节点的 子节点的节点名以及节点值的遍历
List bookChilds = book.getChildren();
for (Element element : bookChilds) {
String name = element.getName();
String value = element.getValue();
System.out.println("节点名:"+name+"~"+"节点值:"+value);
//给book添加属性
if(name.endsWith("name")){
bk.setName(value);
}
else if(name.endsWith("author")){
bk.setAuthor(value);
}
else if(name.endsWith("year")){
bk.setYear(value);
}
else if(name.endsWith("price")){
bk.setPrice(value);
}
else if(name.endsWith("language")){
bk.setLanguage(value);
}
}
list.add(bk);
bk=null;
System.out.println(list);
System.out.println("-------------结束解析第"+(booklist.indexOf(book)+1)+"书-----------");
}
}
0.导入jar包
1.创建SAXReader的对象reader
2.通过reader对象的read方法加载books.xml文件,获取document对象
3.通过document对象获取根节点
4.通过element对象的elementIterator方法获取迭代器
5.遍历迭代器,获取根节点中的信息
6.获取book的属性值及属性名
如果清楚xml文件的结构,也可以用xpath方法快速获取某个具体节点的属性。
private Book bk;//book的实体
private List list=new ArrayList();//存放解析后 生成的book实体
@Test
public void DOM4jPrase() throws DocumentException{
//创建SAXReader的对象reader
SAXReader reader=new SAXReader();
//通过reader对象的read方法加载books.xml文件,获取document对象
org.dom4j.Document document = reader.read(new File("src/res/books.xml"));
//通过document对象获取根节点
org.dom4j.Element bookStore = document.getRootElement();
//通过element对象的elementIterator方法获取迭代器
Iterator elementIterator = bookStore.elementIterator();
//遍历迭代器,获取根节点中的信息
while(elementIterator.hasNext()){
bk=new Book();
System.out.println("====开始遍历某本书====");
org.dom4j.Element book=(org.dom4j.Element) elementIterator.next();
//获取book的属性值及属性名
List attributes = book.attributes();
for (org.dom4j.Attribute attr : attributes) {
String name = attr.getName();
String value = attr.getValue();
System.out.println("节点名:"+name+"~"+"节点值:"+value);
if("id".equals(name)){
bk.setId(value);
}
}
Iterator eit = book.elementIterator();
//遍历每一本书的节点
while(eit.hasNext()){
org.dom4j.Element bookChild = (org.dom4j.Element) eit.next();
String name = bookChild.getName();
String value = bookChild.getStringValue();
System.out.println("节点名:"+name+"~"+"节点值:"+value);
if(name.endsWith("name")){
bk.setName(value);
}
else if(name.endsWith("author")){
bk.setAuthor(value);
}
else if(name.endsWith("year")){
bk.setYear(value);
}
else if(name.endsWith("price")){
bk.setPrice(value);
}
else if(name.endsWith("language")){
bk.setLanguage(value);
}
}
list.add(bk);
bk=null;
System.out.println(list);
System.out.println("===结束遍历某本书====");
}
}
基础方法:DOM、SAX (DOM解析于平台无关的解析)(SAX基于事件驱动)
扩展方法:JDOM,DOM4J
DOM解析 是将xml文件 一次性加载到内存中
SAX解析 事件驱动 startDocument() endDocument() startElement() endElement()
优点 :
*形成了树结构,直观好理解,代码更易于修改
*解析过程中树结构保存在内存中,方便修改
缺点:
*当xml文件很大时,内存消耗比较大容易影响解析性能并可能造成内存溢出
优点:
*采用事件驱动模式,堆内存耗费比较小
*适用于只需要处理xml中数据时
缺点:
*不易于编码
*很难同时访问同一个xml中的多处数据
*仅仅使用具体类而不使用接口
*API大量使用了CollectionS类
*开放源码
*JDOM的一种智能分支,它合并了许多超出基本xml,文档表示的功能
*DOM4J使用接口和抽象基本类方法,是一个优秀的Java XML API
*具有性能优异,灵活性好,功能强大和易于使用的特点
*开放源码
@Test
public void 性能测试() throws Exception{
long s1 = System.currentTimeMillis();
nodePrase();
long s12 = System.currentTimeMillis();
long s2 = System.currentTimeMillis();
SAXParse();
long s22 = System.currentTimeMillis();
long s3 = System.currentTimeMillis();
JDOMPrase();
long s32 = System.currentTimeMillis();
long s4 = System.currentTimeMillis();
DOM4jPrase();
long s42 = System.currentTimeMillis();
System.out.println("DOM"+(s12-s1));
System.out.println("SAX"+(s22-s2));
System.out.println("JDOM"+(s32-s3));
System.out.println("DOM4J"+(s42-s4));
}