解析XML响应并存储到容器中

时间:2015-02-20 15:07:29

标签: java xml http parsing sax

我正在对网站进行HTTP查询,而我得到的响应是XML格式的。我想要做的是进行多个查询,解析数据并将它们放在ArrayList或其他容器中,这样我就可以轻松访问每个查询的数据。我一直在用SAX来解析响应。我读过的例子有这样的XML格式:

<?xml version="1.0"?>
<company>
        <staff>
                <firstname>yong</firstname>
                <lastname>mook kim</lastname>
                <nickname>mkyong</nickname>
                <salary>100000</salary>
        </staff>
        <staff>
                <firstname>low</firstname>
                <lastname>yin fong</lastname>
                <nickname>fong fong</nickname>
                <salary>200000</salary>
        </staff>

我设法通过查看互联网上的示例来轻松解析这样的格式。

但在我的情况下,我需要解析这样的数据:

<?xml version="1.0" encoding="UTF-8"?>
<root response="True">
<movie title="A Good Marriage" year="2014" rated="R" released="03 Oct 2014" runtime="102 min" genre="Thriller" director="Peter Askin" writer="Stephen King (short story)" actors="Joan Allen, Anthony LaPaglia, Stephen Lang, Cara Buono" plot="After 25 years of a good marriage, what will Darcy do once she discovers her husband's sinister secret?" language="English" country="USA" awards="N/A" poster="http://ia.media-imdb.com/images/M/MV5BMTk3MjY2ODgwNl5BMl5BanBnXkFtZTgwMTQ0Mjg0MjE@._V1_SX300.jpg" metascore="43" imdbRating="5.1" imdbVotes="2,016" imdbID="tt2180994" type="movie"/>
</root>

从这个回复中我想把所有的东西解析到一些容器中,所以它很容易使用。我还在学习东西,也许有人可以帮助我,指出正确的方向? :)进行查询不是问题,但解析和存储数据是。

编辑:所以更清楚一点,我的问题是来自服务器的响应不是像第一个例子那样整洁的XML格式,你可以看到它是这样的:

<movie title="A Good Marriage" year="2014" rated="R" released="03 Oct 2014" runtime="102 min" genre="Thriller" director="Peter Askin" writer="Stephen King (short story)" actors="Joan Allen, Anthony LaPaglia, Stephen Lang, Cara Buono" plot="After 25 years of a good marriage, what will Darcy do once she discovers her husband's sinister secret?" language="English" country="USA" awards="N/A" poster="http://ia.media-imdb.com/images/M/MV5BMTk3MjY2ODgwNl5BMl5BanBnXkFtZTgwMTQ0Mjg0MjE@._V1_SX300.jpg" metascore="43" imdbRating="5.1" imdbVotes="2,016" imdbID="tt2180994" type="movie"/>

当我运行我的代码时,它不打印任何东西,但是当我像这样手动修改XML时:

<?xml version="1.0" encoding="UTF-8"?>
<root response="True">
<movie> title="Oblivion" year="2013" rated="PG-13" released="19 Apr 2013" runtime="124 min" genre="Action, Adventure, Mystery" director="Joseph Kosinski" writer="Karl Gajdusek (screenplay), Michael Arndt (screenplay), Joseph Kosinski (graphic novel original story)" actors="Tom Cruise, Morgan Freeman, Olga Kurylenko, Andrea Riseborough" plot="A veteran assigned to extract Earth's remaining resources begins to question what he knows about his mission and himself." language="English" country="USA" awards="10 nominations." poster="http://ia.media-imdb.com/images/M/MV5BMTQwMDY0MTA4MF5BMl5BanBnXkFtZTcwNzI3MDgxOQ@@._V1_SX300.jpg" metascore="54" imdbRating="7.0" imdbVotes="307,845" imdbID="tt1483013" type="movie"/>
</movie>
</root>

所以我为movie-element和结尾标记>添加了结束标记</movie>到最后,我的程序打印出来像:

Movie :  title="Oblivion" year="2013" rated="PG-13" released="19 Apr 2013" runtime="124 min" genre="Action, Adventure, Mystery" director="Joseph Kosinski" writer="Karl Gajdusek (screenplay), Michael Arndt (screenplay), Joseph Kosinski (graphic novel original story)" actors="Tom Cruise, Morgan Freeman, Olga Kurylenko, Andrea Riseborough" plot="A veteran assigned to extract Earth's remaining resources begins to question what he knows about his mission and himself." language="English" country="USA" awards="10 nominations." poster="http://ia.media-imdb.com/images/M/MV5BMTQwMDY0MTA4MF5BMl5BanBnXkFtZTcwNzI3MDgxOQ@@._V1_SX300.jpg" metascore="54" imdbRating="7.0" imdbVotes="307,845" imdbID="tt1483013" type="movie"/>

所以基本上我现在使用的代码会读取<movie></movie>之间的所有内容,问题是来自服务器的原始响应会将电影标记打开,如下所示:<movie title="Oblivion"...并且没有</movie>标记。

我一直在努力奋斗,希望有人理解我令人困惑的解释!目前我的解析器代码如下所示:

public void getXml(){
    try {
        // obtain and configure a SAX based parser
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();

        // obtain object for SAX parser
        SAXParser saxParser = saxParserFactory.newSAXParser();

        // default handler for SAX handler class
        // all three methods are written in handler's body
        DefaultHandler defaultHandler = new DefaultHandler(){

            String movieTag="close";

        // this method is called every time the parser gets an open tag '<'
        // identifies which tag is being open at time by assigning an open flag
        public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {

                if(qName.equalsIgnoreCase("MOVIE")) {
                    movieTag = "open";
                }
            }

        // prints data stored in between '<' and '>' tags
        public void characters(char ch[], int start, int length)
            throws SAXException {

                if(movieTag.equals("open")) {
                    System.out.println("Movie : " + new String(ch, start, length));
                }
            }

        // calls by the parser whenever '>' end tag is found in xml 
        // makes tags flag to 'close'
        public void endElement(String uri, String localName, String qName)
            throws SAXException {

                if(qName.equalsIgnoreCase("MOVIE")) {
                    movieTag = "close";
                }
            }
            };

        // parse the XML specified in the given path and uses supplied
        // handler to parse the document
        // this calls startElement(), endElement() and character() methods
        // accordingly
        saxParser.parse("xml/testi.xml", defaultHandler);
        } catch (Exception e) {
            e.printStackTrace();
            }
    }

请任何人,非常感谢帮助。

1 个答案:

答案 0 :(得分:0)

您仍然可以使用您正在学习的SAX解析器。你没有提到你正在使用的解析器。我使用xerxes(来自Apache.org)。

您可能想要做的是实现一个扩展DefaultHandler的类。如果您使用Eclipse作为IDE,您可以让Eclipse为DefaultHandler中的所有方法实现存根,然后为每个方法添加调试输出,以便更好地了解发生的情况。

但重要的方法是:

public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException

所有字段(标题,年份,评级等)都将在属性数组中提供。

然后你会得到什么:

- 调用startElement - 调用

的startElement

加上你不关心的其他电话。因此,一旦了解了您正在做的事情,您可以删除除调试语句之外的方法,如果您愿意的话。