【问题标题】:SAX Parser: How to read only from `Item` tag?SAX Parser:如何仅从“Item”标签中读取?
【发布时间】:2018-05-22 07:52:12
【问题描述】:

我正在使用 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();
        }

    }

【问题讨论】:

    标签: java android xml saxparser


    【解决方案1】:

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

    【讨论】:

    • 感谢您的回复。你能举个例子吗?
    • 不,SAX 代码是低级且难以编写的,如果您选择使用这样的低级编程接口,那么您将不得不自己完成艰苦的工作。
    • 我选择它是因为它的速度。 DOM 花了将近 2 秒来解析一篇文章,而 sax 似乎要快得多。
    • 我尝试了您的建议并使用新代码更新了我的问题。我还是没有好。你能查一下吗?
    • 当你遇到一个item元素时不应该创建一个新的stack,你应该把遇到的每一个元素名都堆叠起来,而不仅仅是item。如果您只堆叠项目,那么堆叠中的顶部元素将始终是一个项目。
    猜你喜欢
    • 2014-01-23
    • 2012-07-06
    • 1970-01-01
    • 2013-08-29
    • 2011-12-18
    • 1970-01-01
    • 2016-09-30
    • 2023-04-03
    • 1970-01-01
    相关资源
    最近更新 更多