个人项目“RSS FEED”XML解析器

时间:2013-09-21 09:13:06

标签: java xml dom xml-parsing cdata

我对Java比较陌生,而且我一直试图弄清楚如何在几天很长的时间内达到以下输出标签。我真的很感激对这个问题的一些见解。看起来我能找到的所有东西或者只是尝试的东西都没有正确。 (原谅俗气的新闻文章)

<item>
<pubDate>Sat, 21 Sep 2013 02:30:23 EDT</pubDate>
<title>
<![CDATA[
Carmen Bryan Lashes Out at Beyonce Fans for Throwing Shade (@carmenbryan)
]]>
</title>
<link>
http://www.vladtv.com/blog/174937/carmen-bryan-lashes-out-at-beyonce-fans-for-throwing-shade/
</link>
<guid>
http://www.vladtv.com/blog/174937/carmen-bryan-lashes-out-at-beyonce-fans-for-throwing-shade/
</guid>
<description>
<![CDATA[
<img ... /><br />.
 <p>In response to someone who reminded Bryan that Jay Z has Beyonce now, she tweeted.</p>
 <p>Check out what else Bryan had to say above.</p>
 <p>Source: </p>
]]>
</description>
</item>

我已设法解析XML并在title和description元素标记中打印出内容,但description元素标记的输出还包括其所有子元素标记。我希望将来使用这个项目来构建我的Java产品组合,请帮忙!

到目前为止我的代码:

public class NewXmlReader
    {

        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
                try {

                        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                        DocumentBuilder builder = factory.newDocumentBuilder();
                        Document docXml = builder.parse(NewXMLReaderHandlers.inputHandler());
                        docXml.getDocumentElement().normalize();

                        NewXMLReaderHandlers.handleItemTags(docXml, "item");

                } catch (ParserConfigurationException | SAXException parserConfigurationException) {
                        System.out.println("You Are Not XML formated !!");
                        parserConfigurationException.printStackTrace();
                } catch (IOException iOException) {
                        System.out.println("URL NOT FOUND");
                        iOException.getCause();
                }
        }

    }

public class NewXMLReaderHandlers {

    private static int ARTICLELENGTH;

    public static String inputHandler() throws IOException {
        InputStreamReader inputStream = new InputStreamReader(System.in);
        BufferedReader bufferRead = new BufferedReader(inputStream);
        System.out.println("Please Enter A Proper URL: ");
        String urlPageString = bufferRead.readLine();
        return urlPageString;
    }

    public static void handleItemTags( Document document, String rssFeedParentTopicTag){
        NodeList listOfArticles = document.getElementsByTagName(rssFeedParentTopicTag);
        NewXMLReaderHandlers.ARTICLELENGTH = listOfArticles.getLength();
        String rootElement = document.getDocumentElement().getNodeName();
        if (rootElement == "rss"){
            System.out.println("We Have An RSS Feed To Parse");

            for (int i = 0; i < NewXMLReaderHandlers.ARTICLELENGTH; i++) {
                Node itemNode = (Node) listOfArticles.item(i);
                if (itemNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element itemElement= (Element) itemNode;
                    tagContent (itemElement, "title");
                    tagContent (itemElement, "description");
                }
            }
        }

    }

    public static void tagContent (Element item, String tagName) {
            NodeList tagNodeList = item.getElementsByTagName(tagName);
            Element tagElement = (Element)tagNodeList.item(0);
            NodeList tagTElist = tagElement.getChildNodes();
            Node tagNode = tagTElist.item(0);

//          System.out.println( " - " + tagName + " : " + tagNode.getNodeValue() + "\n");
            if(tagName == "description"){
                System.out.println( " - " + tagName + " : " + tagNode.getNodeValue() + "\n\n");
                System.out.println(" Do We Have Any Siblings? " + tagNode.getNextSibling().getNodeValue() + "\n");
            }
        }
    }

2 个答案:

答案 0 :(得分:2)

对于我的钱,最简单的解决方案是使用XPath API。

基本上,它是XML的查询语言。有关入门知识,请参阅XPath Tutorial

此示例使用来自SO的RSS源,它使用<entry...>而不是<item>,但我对其他RSS(和XML)文件甚至非常复杂的HTML文档使用了相同的技术。 ..

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class TestRSSFeed {

    public static void main(String[] args) {
        try {
            // Read the feed...
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            Document doc = factory.newDocumentBuilder().parse("http://stackoverflow.com/feeds/tag?tagnames=java&sort=newest");
            Element root = doc.getDocumentElement();

            // Create a xPath instance
            XPath xPath = XPathFactory.newInstance().newXPath();
            // Find all the nodes that are named <entry...> any where in
            // the document that live under the parent node...
            XPathExpression expression = xPath.compile("//entry");
            NodeList nl = (NodeList) expression.evaluate(root, XPathConstants.NODESET);

            System.out.println("Found " + nl.getLength() + " items...");
            for (int index = 0; index < nl.getLength(); index++) {
                Node node = nl.item(index);
                // This is a sub node search.
                // The search is based on the parent node and looks for a single
                // node titled "title" that belongs to the parent node...
                // I did this because I'm only expecting a single node...
                expression = xPath.compile("title");
                Node child = (Node) expression.evaluate(node, XPathConstants.NODE);
                System.out.println(child.getTextContent());
            }

        } catch (IOException | ParserConfigurationException | SAXException exp) {
            exp.printStackTrace();
        } catch (XPathExpressionException ex) {
            ex.printStackTrace();
        }
    }

}

现在,你可以做一些非常复杂的查询,但我想我会从一个基本的例子开始;)

答案 1 :(得分:0)

万一有人仍然想知道我是如何设法解决CDATA难题的:

逻辑如下:

当程序提取所有xml以显示rss feed显示的正确节点树时,如果任何xml数据包装在CDATA标记中,访问该信息的唯一方法是基于创建新的xml CDATA标记中的文本内容。解析新文档后,您应该能够访问所需的所有数据。