首页 > 解决方案 > SAX Parser:如何仅从“Item”标签中读取?

问题描述

我正在使用 SAX Parser 来解析一些 XML 内容。请在下面检查我的代码。

 public void parse(InputSource is, AppDataBean appDataBean) throws RuntimeException {

        int limitCheck;

        try {

            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            Log.d("SAX",appDataBean.getUrl());


            DefaultHandler handler = new DefaultHandler() {

                boolean title = false;
                boolean link = false;
                boolean author = false;

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

                    if (qName.equalsIgnoreCase(TITLE)) {
                        title = true;
                    }

                    if (qName.equalsIgnoreCase(LINK)) {
                        link = true;
                    }

                    if (qName.equalsIgnoreCase(AUTHOR)) {
                        author = true;
                    }


                    //Log.d("SAX","Start Element :" + qName);



                }

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




                }

                public void characters(char ch[], int start, int length)
                        throws SAXException {

                    System.out.println(new String(ch, start, length));


                    if (title) {
                        Log.d("SAX","End Element :" + "First Name : "
                                + new String(ch, start, length));

                        title = false;
                    }

                    if (link) {


                        Log.d("SAX","End Element :" + "Last Name : "
                                + new String(ch, start, length));
                        link = false;
                    }

                    if (author) {

                        Log.d("SAX","End Element :" + "Nick Name : "
                                + new String(ch, start, length));

                        author = false;
                    }

                }

            };

            saxParser.parse(is, handler);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

下面是我的 XML 的样子。

<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
   <?xml-stylesheet type="text/xsl" href="rss.xsl"?>
   <channel>
      <title>MyRSS</title>
      <atom:link href="http://www.example.com/rss.php" rel="self" type="application/rss+xml" />
      <link>http://www.example.com/rss.php</link>
      <description>MyRSS</description>
      <language>en-us</language>
      <pubDate>Tue, 22 May 2018 13:15:15 +0530</pubDate>
      <item>
         <title>Title 1</title>
         <pubDate>Tue, 22 May 2018 13:14:40 +0530</pubDate>
         <link>http://www.example.com/news.php?nid=47610</link>
         <guid>http://www.example.com/news.php?nid=47610</guid>
         <description>bla bla bla</description>
      </item>
</channel>
</rss>

但是在这里,我需要避免使用该Channel标签,并且只读取根标签是Item. 那么只有我才能得到真正的内容。我怎样才能做到这一点?

更新

正如答案所建议的那样,我尝试将 SAX Parser 与stack. 下面是代码,但我还是不行,现在它什么也没打印First Name

public void parse(InputSource is,  AppDataBean appDataBean) throws RuntimeException {

        int limitCheck;
        stack = new Stack<>();


        try {

            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            Log.d("SAX", appDataBean.getUrl());


            DefaultHandler handler = new DefaultHandler() {

                boolean title = false;
                boolean link = false;
                boolean author = false;

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

                    Log.d("SAX", "localName: " + localName);

                    if(localName.equalsIgnoreCase("item"))
                    {
                        stack = new Stack<>();
                        stack.push(qName);
                    }


                    if (qName.equalsIgnoreCase(TITLE)) {
                        if(stack.peek().equalsIgnoreCase("item"))
                        {
                            title = true;
                        }

                    }

                    if (qName.equalsIgnoreCase(LINK)) {
                        link = true;
                    }

                    if (qName.equalsIgnoreCase(AUTHOR)) {
                        author = true;
                    }


                    //Log.d("SAX","Start Element :" + qName);


                }

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

                    stack.pop();
                }

                public void characters(char ch[], int start, int length)
                        throws SAXException {

                    System.out.println(new String(ch, start, length));


                    if (title) {
                        Log.d("SAX", "End Element :" + "First Name : "
                                + new String(ch, start, length));

                        title = false;
                    }

                    if (link) {


                        Log.d("SAX", "End Element :" + "Last Name : "
                                + new String(ch, start, length));
                        link = false;
                    }

                    if (author) {

                        Log.d("SAX", "End Element :" + "Nick Name : "
                                + new String(ch, start, length));

                        author = false;
                    }

                }

            };

            saxParser.parse(is, handler);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

标签: javaandroidxmlsaxparser

解决方案


通常,SAX 应用程序将维护一个堆栈来保存上下文。在 startElement 事件上,将元素名称压入堆栈;在 endElement 上将其从堆栈中弹出。然后,当您获得标题元素的 startElement 事件时,您可以执行 stack.peek() 以查看标题的父级是什么。


推荐阅读