问答详情
源自:3-4 使用 SAX 解析将 XML 的内容和结构存入 JAVA 对象

为什么我输出的value都是null呢,跟老师一样的代码

输出:

SAX解析开始

=========开始遍历第1本书的内容=========

book元素的第1个属性名是:id---属性值是:1

节点名是:name-----节点值是:冰与火之歌

节点名是:author-----节点值是:乔治马丁

节点名是:year-----节点值是:2014

节点名是:price-----节点值是:89

===========结束遍历第1本书的内容===============

=========开始遍历第2本书的内容=========

book元素的第1个属性名是:id---属性值是:2

节点名是:name-----节点值是:安徒生童话

节点名是:year-----节点值是:2004

节点名是:price-----节点值是:77

节点名是:language-----节点值是:English

===========结束遍历第2本书的内容===============

SAX解析结束

!!!共有2本书!

null

null

null

null

89

null

------finish-------

null

null

null

null

null

English

------finish-------


SAXTest类:

package com.immoc.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 com.imooc.entity.Book;

import com.imooc.handler.SAXPAarserHandler;


public class SAXTest {


public static void main(String[] args) {

//获取一个SAXparserFactory的实例

SAXParserFactory factory=SAXParserFactory.newInstance();

//通过factory获取SAXparser实例

try {

SAXParser parser=factory.newSAXParser();

//创建SAXParserHandler对象

SAXPAarserHandler handler=new SAXPAarserHandler();

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.getYear());

System.out.println(book.getPrice());

System.out.println(book.getLanguage());

System.out.println("------finish-------");

}

} 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();

}


}


}

以下是SAXParseHandler类代码:

package com.imooc.handler;


import java.util.ArrayList;


import javax.xml.stream.events.StartElement;


import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;


import com.imooc.entity.Book;


public class SAXPAarserHandler extends DefaultHandler {

int bookIndex=0;

String value=null;

//创建一个book对象

Book book=null;

private ArrayList<Book> bookList=new ArrayList<Book>();

// /**

// * 

// * 用来遍历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);

// }

public ArrayList<Book> getBookList() {

return bookList;

}

/**

* 用来标识解析开始

*/

@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解析结束");

}

/**

* 解析xml元素

*/

@Override

public void startElement(String uri, String localName, 

String qName, Attributes attributes) throws SAXException {

// TODO Auto-generated method stub

//调用DefaultHandler类的startElemnet方法

super.startElement(uri, localName, qName, attributes);

//开始解析book元素的属性

//创建一个book对象

book=new Book();

if(qName.equals("book")){

bookIndex++;


//开始解析book元素的属性

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.print("book元素的第"+(i+1)+"个属性名是:"

+attributes.getQName(i));

System.out.println("---属性值是:"

+attributes.getValue(i));

//把bookid写入对象

if(attributes.getQName(i).equals("id")){

book.setId(attributes.getValue(i));

}

}

}else if(!qName.equals("book") && !qName.equals("bookstore")){

System.out.print("节点名是:"+qName+"-----");

}

}

@Override

public void endElement(String uri, String localName, String qName) throws SAXException {

//调用DefaultHandler类的endElemnet方法

super.endElement(uri, localName, qName);

//判断是否针对一本书已经遍历结束

if(qName.equals("book")){

bookList.add(book);

book=null;

System.out.println("===========结束遍历第"+bookIndex+"本书的内容===============");

}

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);

}

else if(qName.equals("language")){

book.setLanguage(value);

}

}

@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("节点值是:"+value);

}

}

}

请问到底哪里错了啊,

提问者:thomasstar 2017-02-18 22:25

个回答

  • 丑丶小亚
    2018-02-05 16:04:36

    http://img2.mukewang.com/5a780eeb0001e22508430212.jpg

    楼上的正解。startElement方法遇到节点就解析,你的代码相当于每次都在new Book();

    至于为什么还是有2个book,是因为你在endElement方法的时候判断book标签了,而book结束标签只有2个,

    所以你添加了2个null的book内容。

  • 不才小子
    2017-02-20 22:07:22

    终于搞明白了,为啥你输出的都是null。

    book=new Book();

    if(qName.equals("book")){

    bookIndex++;

    应该是每次访问的book标签时创建book对象,而不是你代码里写的每个标签开始都创建一个book对象。

    因为一直在新建book对象,所以只能存储当前的属性值,下一个标签值就自动变成null

  • thomasstar
    2017-02-19 15:06:51

    这是book类

    package com.imooc.entity;


    public class Book {

    private String id;

    private String name;

    private String author;

    private String year;

    private String price;

    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 getAuthor() {

    return author;

    }

    public void setAuthor(String author) {

    this.author = author;

    }

    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;

    }

    public String getLanguage() {

    return language;

    }

    public void setLanguage(String language) {

    this.language = language;

    }

    }


  • 不才小子
    2017-02-19 14:49:04

    可以看一下你的Book类怎么写的吗?另外SAXTest类的包名package com.immoc.test;是不是打错了?